这道题看到操作4就能想到使用可持久化数据结构
对于这一题的初始想法,是把二维映射到一维,前两个操作是单点修改,第三个是区间01反转
感觉应该是可做的,但是不太好写。
一种好写的做法是,维护行,对于每行维护一个bitset,这样三种操作就都很容易做了
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e5+10; const int mod=998244353; struct node{ int l,r; int sum; bitset<1010> bt; }tr[N*10]; int n,m; int rt[N],idx; bitset<1010> bs; void build(int &u,int l,int r){ u=++idx; if(l==r){ return ; } else{ int mid=l+r>>1; build(tr[u].l,l,mid); build(tr[u].r,mid+1,r); } } void modify(int &p,int q,int l,int r,int opt,int x,int y){ p=++idx; tr[p]=tr[q]; if(l==r){ if(opt==1){ tr[p].bt.set(y); } else if(opt==2){ tr[p].bt.reset(y); } else{ tr[p].bt^=bs; } tr[p].sum=tr[p].bt.count(); return ; } int mid=l+r>>1; if(x<=mid) modify(tr[p].l,tr[q].l,l,mid,opt,x,y); else modify(tr[p].r,tr[q].r,mid+1,r,opt,x,y); tr[p].sum=tr[tr[p].l].sum+tr[tr[p].r].sum; } int main(){ ios::sync_with_stdio(false); int q; cin>>n>>m>>q; int i; build(rt[0],1,n); for(i=1;i<=m;i++){ bs.set(i); } for(i=1;i<=q;i++){ int opt; cin>>opt; int l,r; if(opt==1){ cin>>l>>r; modify(rt[i],rt[i-1],1,n,1,l,r); } else if(opt==2){ cin>>l>>r; modify(rt[i],rt[i-1],1,n,2,l,r); } else if(opt==3){ cin>>l; modify(rt[i],rt[i-1],1,n,3,l,0); } else{ int k; cin>>k; rt[i]=rt[k]; } cout<<tr[rt[i]].sum<<endl; } return 0; }View Code