NOI十连测 第四测 T2

 思路:线段树套可持久化treap,可持久化treap我还是第一次听说。。

改题的时候没看数据范围。。乱开数组T_T

  1 #include<algorithm>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<iostream>
  6 #include<time.h>
  7 #include<bits/stdc++.h>
  8 #include<ext/rope>
  9 using namespace std;
 10 using namespace __gnu_cxx;
 11 int n;
 12 int read(){
 13     int t=0,f=1;char ch=getchar();
 14     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 15     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
 16     return t*f;
 17 }
 18 struct treaps{
 19     int ch[30001005][2],rnd[30001005],size[30001005],num[30001005],tt;
 20     int newnode(int s=0){
 21         if (tt>30000005) assert(0);
 22         ++tt;
 23         ch[tt][0]=ch[s][0];
 24         ch[tt][1]=ch[s][1];
 25         if (s) rnd[tt]=rnd[s];else rnd[tt]=rand();
 26         size[tt]=size[s];
 27         num[tt]=num[s];
 28         return tt;
 29     }
 30     void updata(int k){
 31         size[k]=1+size[ch[k][0]]+size[ch[k][1]];
 32     }
 33     int getsize(int k){
 34         return size[k];
 35     }
 36     int merge(int s,int t){
 37         if (!s||!t) return s+t;
 38         if (rnd[s]>rnd[t]){
 39             int d=newnode(s);
 40             ch[d][1]=merge(ch[d][1],t);
 41             updata(d);
 42             return d;
 43         }else{
 44             int d=newnode(t);
 45             ch[d][0]=merge(s,ch[d][0]);
 46             updata(d);
 47             return d;
 48         }
 49     }
 50     pair<int,int> split(int s,int k){
 51         if (!s) return make_pair(0,0);
 52         if (size[ch[s][0]]>=k){
 53             pair<int,int> ls=split(ch[s][0],k);
 54             int d=newnode(s);
 55             ch[d][0]=ls.second;updata(d);
 56             return pair<int,int>(ls.first,d);
 57         }
 58         pair<int,int> ls=split(ch[s][1],k-size[ch[s][0]]-1);
 59         int d=newnode(s);
 60         ch[d][1]=ls.first;updata(d);
 61         return pair<int,int>(d,ls.second);
 62     }
 63     void clear(int &s){
 64         s=0;
 65     }
 66     void push_back(int &s,int w){
 67         int d=newnode();size[d]=1;num[d]=w;
 68         s=merge(s,d);
 69     }
 70     void pop_back(int &s){
 71         s=split(s,size[s]-1).first;
 72     }
 73     int findkth(int s,int k){
 74         if (size[ch[s][0]]>=k) return findkth(ch[s][0],k);
 75         if (size[ch[s][0]]+1==k) return num[s];
 76         return findkth(ch[s][1],k-size[ch[s][0]]-1);
 77     }
 78 }treap;
 79 struct segment{
 80     int tt,l[4001005],r[4001005];
 81     int ins[4001005];
 82     int erz[4001005];
 83     int build(int ql=1,int qr=n){
 84         int t=++tt;
 85         int mid=(ql+qr)>>1;
 86         if (ql==qr) return t;
 87         l[t]=build(ql,mid);
 88         r[t]=build(mid+1,qr);
 89         return t;
 90     }
 91     void pushdown(int root){
 92         if (erz[root]){
 93             if (treap.getsize(ins[l[root]])<=erz[root]){
 94                 erz[l[root]]+=erz[root]-treap.getsize(ins[l[root]]);
 95                 treap.clear(ins[l[root]]);
 96             }else ins[l[root]]=treap.split(ins[l[root]],treap.getsize(ins[l[root]])-erz[root]).first;
 97             
 98             if (treap.getsize(ins[r[root]])<=erz[root]){
 99                 erz[r[root]]+=erz[root]-treap.getsize(ins[r[root]]);
100                 treap.clear(ins[r[root]]);
101             }else ins[r[root]]=treap.split(ins[r[root]],treap.getsize(ins[r[root]])-erz[root]).first;
102             erz[root]=0;
103         }
104         if (treap.getsize(ins[root])){
105             ins[l[root]]=treap.merge(ins[l[root]],ins[root]);
106             ins[r[root]]=treap.merge(ins[r[root]],ins[root]);
107             treap.clear(ins[root]);
108         }
109     }
110     void push(int root,int ql,int qr,int w,int pl=1,int pr=n){
111         if ((ql==pl)&&(pr==qr)){
112             treap.push_back(ins[root],w);
113             return;
114         }
115         pushdown(root);
116         int mid=(pl+pr)>>1;
117         if (ql<=mid) push(l[root],ql,min(qr,mid),w,pl,mid);
118         if (qr>mid) push(r[root],max(mid+1,ql),qr,w,mid+1,pr);
119     }
120     void pop(int root,int ql,int qr,int pl=1,int pr=n){
121         if ((ql==pl)&&(qr==pr)){
122             if (treap.getsize(ins[root])) treap.pop_back(ins[root]);
123             else erz[root]++;
124             return;
125         }
126         pushdown(root);
127         int mid=(pl+pr)>>1;
128         if (ql<=mid) pop(l[root],ql,min(mid,qr),pl,mid);
129         if (qr>mid) pop(r[root],max(ql,mid+1),qr,mid+1,pr);
130     }
131     void work(int root,int s,int k,int pl=1,int pr=n){
132         if (pl==pr){
133             if (treap.getsize(ins[root])<k) printf("Error\n");
134             else
135             printf("%d\n",treap.findkth(ins[root],treap.getsize(ins[root])-k+1));
136             return;
137         }
138         pushdown(root);
139         int mid=(pl+pr)>>1;
140         if (s<=mid) work(l[root],s,k,pl,mid);
141         else work(r[root],s,k,mid+1,pr);
142     }
143 }seg;
144 int main(){
145     n=read();int q=read();
146     seg.build();
147     while (q--){
148         int opt=read();
149         if (opt==0){
150             int l=read(),r=read(),x=read();
151             seg.push(1,l,r,x);
152         }else
153         if (opt==1){
154             int l=read(),r=read();
155             seg.pop(1,l,r);
156         }else
157         if (opt==2)
158         {
159             int s=read(),k=read();
160             seg.work(1,s,k);
161         }
162     }
163 }

 

posted @ 2016-06-20 09:16  GFY  阅读(251)  评论(0编辑  收藏  举报