J

来源:互联网 发布:最靠谱的网络兼职 编辑:程序博客网 时间:2024/06/10 03:54

题目描述

这里写图片描述

分块

2*3的矩形可以压成64以内的二进制数。
我们分块,对于每块,维护块内每个前缀异或的桶,以及整个块异或值,因为有区间修改还要有修改tag,然后便容易询问与修改。

#include<cstdio>#include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)using namespace std;const int maxn=1000000+10,maxd=64;int cnt[maxn/100+10][maxd+10],num[maxn/100+10],tag[maxn/100+10],belong[maxn],ac[20];int id[20][20];int a[maxn];bool bz[maxn/100+10];int i,j,k,l,t,n,m,r,q,wdc,B;int read(){    int x=0,f=1;    char ch=getchar();    while (ch<'0'||ch>'9'){        if (ch=='-') f=-1;        ch=getchar();    }    while (ch>='0'&&ch<='9'){        x=x*10+ch-'0';        ch=getchar();    }    return x*f;}void mark(int x,int v){    bz[x]=1;    tag[x]=v;}void down(int x){    if (!bz[x]) return;    int i;    fo(i,(x-1)*B+1,min(B*x,n)) a[i]=ac[tag[x]];    bz[x]=0;}void rebuild(int x){    down(x);    int i,t=0;    fo(i,0,maxd-1) cnt[x][i]=0;    fo(i,(x-1)*B+1,min(B*x,n)){        t^=a[i];        cnt[x][t]++;    }    num[x]=t;}int query(int j,int k){    int i,t=0,ans=0,x;    int l=belong[j],r=belong[k];    if (l==r){        fo(i,1,l-1){            if (bz[i]){                if (B%2) t^=ac[tag[i]];            }            else t^=num[i];        }        fo(i,(l-1)*B+1,min(l*B,n)){            if (bz[l]) t^=ac[tag[l]];else t^=a[i];            if (j<=i&&i<=k&&t==wdc) ans++;        }        return ans;    }    fo(i,1,l-1){        if (bz[i]){            if (B%2) t^=ac[tag[i]];        }        else t^=num[i];    }    fo(i,(l-1)*B+1,l*B){        if (bz[l]) t^=ac[tag[l]];else t^=a[i];        if (j<=i&&t==wdc) ans++;    }    fo(i,l+1,r-1){        if (bz[i]){            if ((ac[tag[i]]^t)==wdc) ans+=(B+1)/2;            if (t==wdc) ans+=B/2;            if (B%2) t^=ac[tag[i]];        }        else{            ans+=cnt[i][wdc^t];            t^=num[i];        }    }    fo(i,(r-1)*B+1,k){        if (bz[r]) t^=ac[tag[r]];else t^=a[i];        if (t==wdc) ans++;    }    return ans;}void change(int j,int k,int v){    int i;    int l=belong[j],r=belong[k];    if (l==r){        down(l);        fo(i,j,k) a[i]=ac[v];        rebuild(l);        return;    }    fo(i,l+1,r-1) mark(i,v);    down(l);    fo(i,j,l*B) a[i]=ac[v];    rebuild(l);    down(r);    fo(i,(r-1)*B+1,k) a[i]=ac[v];    rebuild(r);}int main(){    freopen("ji.in","r",stdin);freopen("ji.out","w",stdout);    n=read();m=read();    wdc=0;    fo(i,1,n)        fo(j,1,m){            t=read();            wdc=wdc*2+t;        }    t=0;    fd(i,n,1)        fd(j,m,1)            id[i][j]=t++;    fo(i,1,n){        ac[i]=0;        fo(j,1,m) ac[i]+=(1<<id[i][j]);    }    fo(j,1,m){        ac[j+n]=0;        fo(i,1,n) ac[j+n]+=(1<<id[i][j]);    }    n=read();m=read();    //B=floor(sqrt(n));    //B=1;    B=600;    fo(i,1,n) belong[i]=(i-1)/B+1;    fo(i,1,belong[n]){        mark(i,1);        rebuild(i);    }    while (m--){        t=read();        if (t==0){            j=read();k=read();            down(belong[j]);            a[j]=ac[k];            rebuild(belong[j]);        }        else if (t==1){            j=read();k=read();            printf("%d\n",query(j,k));        }        else{            j=read();k=read();l=read();            change(j,k,l);        }    }}
0 0
原创粉丝点击