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 }