[cf707D]Persistent Bookcase

显然可以写可持久化树套树,然而实际上由于只有一整行的修改和单点修改,并没有一个小矩形的修改,所以可以将其转化到一个序列上,只需要写可持久化线段树就可以了(然而标算是操作树)。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define ll long long
 6 #define mid ((l+r)>>1)
 7 #define L(k) f[k].l
 8 #define R(k) f[k].r
 9 #define maxN 1000001
10 #define maxT 100001
11 struct ji{
12     int l,r,lazy,sum;
13 }f[4*maxN+20*maxT];
14 int N,n,m,q,p,k,x,y,now,R[maxT];
15 void up(int k,int l,int r){
16     f[k].sum=f[L(k)].sum+f[R(k)].sum;
17     if (f[k].lazy)f[k].sum=r-l+1-f[k].sum;
18 }
19 void build(int &k,int l,int r){
20     k=++N;
21     if (l==r)return;
22     build(L(k),l,mid);
23     build(R(k),mid+1,r);
24     up(k,l,r);
25 }
26 void update(int &root,int k,int l,int r,int x,int y){
27     if ((r<x)||(l>x))return;
28     f[root=++N]=f[k];
29     if (l==r){
30         f[root].sum=y;
31         return;
32     }
33     y^=f[k].lazy;
34     update(L(root),L(k),l,mid,x,y);
35     update(R(root),R(k),mid+1,r,x,y);
36     up(root,l,r);
37 }
38 void update2(int &root,int k,int l,int r,int x,int y){
39     if ((y<l)||(r<x))return;
40     f[root=++N]=f[k];
41     if ((x<=l)&&(r<=y)){
42         f[root].lazy^=1;
43         f[root].sum=r-l+1-f[root].sum;
44         return;
45     }
46     update2(L(root),L(k),l,mid,x,y);
47     update2(R(root),R(k),mid+1,r,x,y);
48     up(root,l,r);
49 }
50 int main(){
51     scanf("%d%d%d",&n,&m,&q);
52     build(R[0],1,n*=m);
53     for(int i=1;i<=q;i++){
54         scanf("%d%d",&p,&x);
55         now++;
56         if (p<=2){
57             scanf("%d",&y);
58             update(R[i],R[i-1],1,n,(x-1)*m+y,p&1);
59         }
60         if (p==3)update2(R[i],R[i-1],1,n,(x-1)*m+1,x*m);
61         if (p==4)R[i]=R[x];
62         printf("%d\n",f[R[i]].sum);
63     }
64 }
View Code

 

posted @ 2019-07-28 10:31  PYWBKTDA  阅读(144)  评论(0编辑  收藏  举报