Description
由于题面过于丧心病狂就直接贴图了
Solution
可以把每个操作变成2进制的异或操作。
那么就是修改加询问前缀异或和为st的数的个数。
线段树\分块都可以做啊。
一个优化:有用的状态只有16种,可以提前处理出来。
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int N=1e6+5,M=600,S=N/M+5;
int n,m,R,Q,op,x,y,z,u,v,ans,tot,size,st;
int f[S][17],s[S],l[S],r[S],tag[S],id[N],mi[6],c[6],h[65];
int get(int x,int y) { return (x-1)*m+y-1; }
void dfs(int x,int z) {
if (x>n+m) {
if (h[z]) return;
h[z]=++tot;
return;
}
z^=c[x];dfs(x+1,z);
z^=c[x];dfs(x+1,z);
}
int find(int x) {
fo(i,1,size)
if (l[i]<=x&&x<=r[i])
return i;
}
void updata(int x) {
s[x]=0;fo(i,1,tot) f[x][i]=0;
fo(i,l[x],r[x]) f[x][h[s[x]^=c[id[i]]]]++;
}
void down(int x) {
if (!tag[x]) return;
fo(i,l[x],r[x]) id[i]=tag[x];
tag[x]=0;updata(x);
}
int main() {
freopen("ji.in","r",stdin);
freopen("ji.out","w",stdout);
scanf("%d%d",&n,&m);
mi[0]=1;fo(i,1,n+m) mi[i]=mi[i-1]*2;
fo(i,1,n)
fo(j,1,m)
c[i]+=mi[get(i,j)];
fo(i,n+1,n+m)
fo(j,1,n)
c[i]+=mi[get(j,i-n)];
fo(i,1,n)
fo(j,1,m) {
scanf("%d",&x);
st+=mi[get(i,j)]*x;
}
dfs(1,0);
scanf("%d%d",&R,&Q);
size=(R-1)/M+1;
fo(i,1,R) id[i]=1;
fo(i,1,size) {
l[i]=r[i-1]+1;
r[i]=min(l[i]+M-1,R);
updata(i);
}
for(;Q;Q--) {
scanf("%d",&op);
if (!op) {
scanf("%d%d",&x,&y);
u=find(x);down(u);
id[x]=y;updata(u);
} else if (op==1) {
scanf("%d%d",&x,&y);
u=find(x);v=find(y);
down(u);down(v);
int cnt=0,ans=0;
fo(i,1,u-1)
if (tag[i]) {
if ((r[i]-l[i]+1)&1)
cnt^=c[tag[i]];
} else cnt^=s[i];
fo(i,l[u],x-1) cnt^=c[id[i]];
if (u==v) {
fo(i,x,y) {
cnt^=c[id[i]];
if (cnt==st) ans++;
}
printf("%d\n",ans);
continue;
}
fo(i,x,r[u]) {
cnt^=c[id[i]];
if (cnt==st) ans++;
}
fo(i,u+1,v-1)
if (tag[i]) {
if (cnt==st) ans+=(r[i]-l[i]+1)/2;
else if ((cnt^c[tag[i]])==st) ans+=(r[i]-l[i]+2)/2;
if ((r[i]-l[i]+1)&1) cnt^=c[tag[i]];
} else {
ans+=f[i][h[st^cnt]];
cnt^=s[i];
}
fo(i,l[v],y) {
cnt^=c[id[i]];
if (cnt==st) ans++;
}
printf("%d\n",ans);
} else {
scanf("%d%d%d",&x,&y,&z);
u=find(x);v=find(y);
down(u);down(v);
if (u==v) {
fo(i,x,y) id[i]=z;
updata(u);
continue;
}
fo(i,x,r[u]) id[i]=z;
fo(i,l[v],y) id[i]=z;
fo(i,u+1,v-1) tag[i]=z;
updata(u);updata(v);
}
}
}