Codeforces Round #198 (Div. 1) D. Iahub and Xors 二维树状数组*
Iahub does not like background stories, so he'll tell you exactly what this problem asks you for.
You are given a matrix a with n rows and n columns. Initially, all values of the matrix are zeros. Both rows and columns are 1-based, that is rows are numbered 1, 2, ..., n and columns are numbered 1, 2, ..., n. Let's denote an element on the i-th row and j-th column as ai, j.
We will call a submatrix (x0, y0, x1, y1) such elements ai, j for which two inequalities hold: x0 ≤ i ≤ x1, y0 ≤ j ≤ y1.
Write a program to perform two following operations:
- Query(x0, y0, x1, y1): print the xor sum of the elements of the submatrix (x0, y0, x1, y1).
- Update(x0, y0, x1, y1, v): each element from submatrix (x0, y0, x1, y1) gets xor-ed by value v.
The first line contains two integers: n (1 ≤ n ≤ 1000) and m (1 ≤ m ≤ 105). The number m represents the number of operations you need to perform. Each of the next m lines contains five or six integers, depending on operation type.
If the i-th operation from the input is a query, the first number from i-th line will be 1. It will be followed by four integers x0, y0, x1, y1. If thei-th operation is an update, the first number from the i-th line will be 2. It will be followed by five integers x0, y0, x1, y1, v.
It is guaranteed that for each update operation, the following inequality holds: 0 ≤ v < 262. It is guaranteed that for each operation, the following inequalities hold: 1 ≤ x0 ≤ x1 ≤ n, 1 ≤ y0 ≤ y1 ≤ n.
For each query operation, output on a new line the result.
3 5
2 1 1 2 2 1
2 1 3 2 3 2
2 3 1 3 3 3
1 2 2 3 3
1 2 2 3 2
3
2
After the first 3 operations, the matrix will look like this:
1 1 2
1 1 2
3 3 3
The fourth operation asks us to compute 1 xor 2 xor 3 xor 3 = 3.
The fifth operation asks us to compute 1 xor 3 = 2.
题意:
给你一个n×n的矩阵;初始时所有位置的值都为0;
m次操作:两种操作,一种是将某个矩形区域的值异或v,另一种是求一个矩形区域的异或和。
题解:
想办法维护(1,1)(x,y)的异或和,那么矩形区域的异或和就可以根据四个位置的异或和求出。由于异或操作比较特殊,在一个区域进行异或操作,那么这个区域的某个点的(1,1)(x,y)的异或和要么要异或上v,要么异或上0。这样,我们就可以利用二维树状数组,只进行单点更新就完成更新矩形区域的操作,另外,由于区域是否被更新跟奇偶性有关,因此跟据奇偶性来维护4种情况的树状数组。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18+1LL; const double Pi = acos(-1.0); const int N = 1e3+10, M = 1e5+20, mod = 1e9+7, inf = 2e9; int n,m,mp[N][N]; LL C[4][N][N]; int get(int x,int y) { int res = 0; if(x&1) res += 1; if(y&1) res += 2; return res; } LL ask(int x,int y) { LL s = 0; int wh = get(x,y); for(int i = x; i; i-= i & (-i)) for(int j = y; j; j -= j & (-j)) s^=C[wh][i][j]; return s; } void update(int x,int y,LL v) { int wh = get(x,y); for(int i = x; i < N; i+= i&(-i)) for(int j = y; j < N; j += j&(-j)) C[wh][i][j] ^= v; } int main() { scanf("%d%d",&n,&m); for(int i = 1; i <= m; ++i) { int op,x1,x2,y1,y2; LL v; scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2); if(op == 1) { LL a = ask(x2,y2); LL b = 0, c = 0, d = 0; if(y1 > 1) b = ask(x2,y1-1); if(x1 > 1) c = ask(x1-1,y2); if(x1 > 1 && y1 > 1) d = ask(x1-1,y1-1); printf("%I64d\n",a^b^d^c); } else { scanf("%I64d",&v); update(x2+1,y2+1,v); update(x2+1,y1,v); update(x1,y2+1,v); update(x1,y1,v); } } return 0; }