문제: icpc.me/12844
특정 구간에 XOR을 하거나 구간을 XOR한 값을 출력하는 문제이다.
N,M이 50만이므로 구간에 대한 쿼리를 빠르게 처리 하기 위해 세그먼트 트리를 사용해야 한다.
이때 한 지점에 대해서가 아닌 구간에 대한 업데이트가 이루어지므로 lazy propagation을 이용하여 최적화 시켜줄 필요가 있다.
주의해야 할 점은 항상 a가 b보다 작지는 않다는 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #include <cstdio> #include <algorithm> using namespace std; int n, m, a, b, c, d; int seg[4004000]; int lazy[4004000]; void u_lazy(int node, int x, int y) { if (!lazy[node]) return; if ((y - x + 1) % 2) seg[node] ^= lazy[node]; if (x == y) { lazy[node] = 0; return; } lazy[node * 2] ^= lazy[node]; lazy[node * 2 + 1] ^= lazy[node]; lazy[node] = 0; } void update(int lo, int hi, int val, int node, int x, int y) { u_lazy(node, x, y); if (y < lo || hi < x)return; if (lo <= x&&y <= hi) { if ((y - x + 1) % 2)seg[node] ^= val; if (x == y)return; lazy[node * 2] ^= val; lazy[node * 2 + 1] ^= val; return; } int mid = (x + y) >> 1; update(lo, hi, val, node * 2, x, mid); update(lo, hi, val, node * 2 + 1, mid + 1, y); seg[node] = seg[node * 2] ^ seg[node * 2 + 1]; } int query(int lo, int hi, int node, int x, int y) { u_lazy(node, x, y); if (y < lo || hi < x) return 0; if (lo <= x&&y <= hi) return seg[node]; int mid = (x + y) >> 1; return query(lo, hi, node * 2, x, mid) ^ query(lo, hi, node * 2 + 1, mid + 1, y); } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &a); update(i, i, a, 1, 0, n - 1); } scanf("%d", &m); for (int i = 0; i < m; i++) { scanf("%d", &a); if (a == 1) { scanf("%d%d%d", &b, &c, &d); update(min(b, c), max(b, c), d, 1, 0, n - 1); } else { scanf("%d%d", &b, &c); printf("%d\n", query(min(b, c), max(b, c), 1, 0, n - 1)); } } return 0; } | cs |
'알고리즘 관련 > BOJ' 카테고리의 다른 글
BOJ)12845 모두의 마블 (0) | 2017.01.03 |
---|---|
BOJ)12846 무서운 아르바이트 (0) | 2017.01.03 |
BOJ)10815 숫자 카드 (0) | 2017.01.03 |
BOJ)1733 등번호 (2) | 2017.01.03 |
BOJ)14168 Cow Checklist (0) | 2017.01.03 |