//cf707d /* 题意:维护一个图,支持四种操作 1.第i行第j列变为1 2.第i行第j列变为0 3.第i行颠倒,1变0,0变1 4.将整张图变为第k次操作时的状态,如果k是0的话,则清空图 */ #include<bits/stdc++.h> using namespace std; const int maxn=1e6+100; const int M=maxn*6; struct node { int l,r,lazy,sum; }segTree[M]; int T[maxn]; int tot,n,m,q; void pushdown (int i,int l,int r) { segTree[i].sum=segTree[segTree[i].l].sum+segTree[segTree[i].r].sum; if (segTree[i].lazy) segTree[i].sum=r-l+1-segTree[i].sum; } void build (int &rt,int l,int r) { rt=++tot; if (l==r) return; int mid=(l+r)>>1; build(segTree[rt].l,l,mid); build(segTree[rt].r,mid+1,r); pushdown(rt,l,r); } void up (int &rt,int k,int l,int r,int x,int y) { if (r<x||l>x) return; rt=++tot; segTree[rt]=segTree[k]; if (l==r) { segTree[rt].sum=y; return; } y^=segTree[k].lazy; int mid=(l+r)>>1; up(segTree[rt].l,segTree[k].l,l,mid,x,y); up(segTree[rt].r,segTree[k].r,mid+1,r,x,y); pushdown(rt,l,r); } void up2 (int &rt,int k,int l,int r,int x,int y) { if (r<x||l>y) return; rt=++tot; segTree[rt]=segTree[k]; if (x<=l&&y>=r) { segTree[rt].lazy^=1; segTree[rt].sum=r-l+1-segTree[rt].sum; return; } int mid=(l+r)>>1; up2(segTree[rt].l,segTree[k].l,l,mid,x,y); up2(segTree[rt].r,segTree[k].r,mid+1,r,x,y); pushdown(rt,l,r); } int main () { scanf("%d%d%d",&n,&m,&q); build(T[0],1,n*m); for (int i=1;i<=q;i++) { int p,x; scanf("%d%d",&p,&x); if (p<=2) { int y; scanf("%d",&y); up(T[i],T[i-1],1,n*m,(x-1)*m+y,p&1); } if (p==3) { up2(T[i],T[i-1],1,n*m,(x-1)*m+1,x*m); } if (p==4) T[i]=T[x]; printf("%d ",segTree[T[i]].sum); } }