SCL--二维BIT(区间修改、区间查询)
2016-09-18 23:56:11
题目来源:CF 341D
题意:1000*1000的矩阵,子矩阵异或,子矩阵异或和。
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <map> #include <set> #include <queue> #include <iostream> #include <algorithm> using namespace std; #define lp (p << 1) #define rp (p << 1|1) #define getmid(l,r) (l + (r - l) / 2) #define MP(a,b) make_pair(a,b) #define PB push_back typedef long long ll; typedef pair<int,int> pii; const int INF = (1 << 30) - 1; using namespace std; const int MAXN = 1010; int N,M; struct BIT{ ll a[MAXN][MAXN]; inline int lowbit(int &x){ return x & (-x); } inline void add(int x,int y,ll t){ for(int i = x; i <= N; i += lowbit(i)) for(int j = y; j <= N; j += lowbit(j)) a[i][j] ^= t; } inline ll get(int x,int y){ ll res = 0; for(int i = x; i; i -= lowbit(i)) for(int j = y; j; j -= lowbit(j)) res ^= a[i][j]; return res; } }; struct BIT_2D{ BIT A,B,C,D; inline void Add(int x,int y,ll t){ A.add(x,y,t); if(x & 1) B.add(x,y,t); if(y & 1) C.add(x,y,t); if((x * y) & 1) D.add(x,y,t); } inline void Add(int x1,int y1,int x2,int y2,ll t){ Add(x1,y1,t); Add(x1,y2 + 1,t); Add(x2 + 1,y1,t); Add(x2 + 1,y2 + 1,t); } inline ll Get(int x,int y){ ll res = D.get(x,y); if(((x + 1) * (y + 1)) & 1) res ^= A.get(x,y); if((y + 1) & 1) res ^= B.get(x,y); if((x + 1) & 1) res ^= C.get(x,y); return res; } inline ll Get(int x1,int y1,int x2,int y2){ return Get(x2,y2) ^ Get(x1 - 1,y1 - 1) ^ Get(x2,y1 - 1) ^ Get(x1 - 1,y2); } }B2; int main(){ scanf("%d%d",&N,&M); for(int i = 1; i <= M; ++i){ int op,X1,Y1,X2,Y2; ll v; scanf("%d%d%d%d%d",&op,&X1,&Y1,&X2,&Y2); if(op == 1){ printf("%I64d\n",B2.Get(X1,Y1,X2,Y2)); } else{ scanf("%I64d",&v); B2.Add(X1,Y1,X2,Y2,v); } } return 0; }