lahub and Xors
题目大意
给你一个矩阵,要你实现子矩阵异或上一个数,查询子矩阵异或和。
Solution
一眼望过去:哇妈妈这个我会二维线段树!
然后TLE+MLE
考虑树状数组,采用差分思想
我们设\(d[i][j]=a[i][j] \bigoplus a[i-1][j] \bigoplus a[i][j-1] \bigoplus a[i-1][j-1]\)(a为原矩阵)(出格的格子当成0)
那么我们查询\((1,1,x,y)\)的时候只需要查询和自己奇偶性相同的格子上的\(d\)就好了
所以建立四个树状数组,然后子矩阵的查询差分一下就好了
接下来考虑一下怎么搞修改
我们看一看我们修改的时候\(d\)发生了什么变化:(图可能有点小,把它扯出来看就好了)
这题真的棒,超级思维题
code:
#include<bits/stdc++.h> using namespace std; #define int long long int read(){ int num=0; bool f=0; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-')f=1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return f?-num:num; } int write(int x){ if(x<0){putchar('-');x=~(x-1);} int s[20],top=0; while(x){s[++top]=x%10;x/=10;} if(!top)s[++top]=0; while(top)putchar(s[top--]+'0'); putchar('\n'); } int c[4][1010][1010]; int n,m; inline int lowbit(int x){return x&-x;} void update(int type,int x,int y,int v){ while(x<=n){ int i=y; while(i<=n){ c[type][x][i]^=v; i+=lowbit(i); } x+=lowbit(x); } } int query(int type,int y){ int ans=0; while(x){ int i=y; while(i){ ans^=c[type][x][i]; i-=lowbit(i); } x-=lowbit(x); } return ans; } int turn(int x,int y){ return (x&1)+((y&1)<<1); } void update(int x0,int y0,int x1,int y1,int v){ int t1=turn(x1+1,y1+1),t2=turn(x1+1,y0),t3=turn(x0,t4=turn(x0,y0); //cout<<t1<<" "<<t2<<" "<<t3<<" "<<t4<<endl; update(t1,x1+1,y1+1,v); update(t2,y0,v); update(t3,x0,v); update(t4,v); } int query(int x0,int y1){ int t1=turn(x1,y1),t2=turn(x1,y0-1),t3=turn(x0-1,t4=turn(x0-1,y0-1); int ans=0; ans^=query(t1,x1,y1); ans^=query(t2,y0-1); ans^=query(t3,x0-1,y1); ans^=query(t4,y0-1); return ans; } signed main(){ n=read(),m=read(); for(int i=1;i<=m;++i){ int opt=read(),x0=read(),y0=read(),x1=read(),y1=read(); if(opt==1){ write(query(x0,y1)); } else { int v=read(); update(x0,y1,v); } } }