1901: Zju2112 Dynamic Rankings
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5268 Solved: 2207
[Submit][Status][Discuss]
Description
给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。你需要编一个这样的程序,从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令。对于每一个询问指令,你必须输出正确的回答。 第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。分别表示序列的长度和指令的个数。第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。接下来的m行描述每条指令,每行的格式是下面两种格式中的一种。 Q i j k 或者 C i t Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t。
Input
对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。
Output
Sample Input
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
Sample Output
6
HINT
20%的数据中,m,n≤100; 40%的数据中,m,n≤1000; 100%的数据中,m,n≤10000。
Source
题解:人生中的一个A掉的树套树,就是线段树套Treap树,线段树每一个点所代表的不再是一个简单的点,而是一棵Treap树,然后每次修改将要牵扯到logN棵树,然后每棵树复杂度为logN,所以修改操作是log^2N的,然后就是区间第K大了,显然,查询区间内某数排名在上面的基础上并不难做(其实就是查询有多少个数字小于它然后再+1),然后就是确定最大最小值然后二分一下,这样一来复杂度为log^3N,然后然后没别的了(Hansbug:此程序里面的删除操作和求区间第K大操作是按照hzwer神犇的写法来写的orz)
1 /************************************************************** 2 Problem: 1901 3 User: HansBug 4 Language: Pascal 5 Result: Accepted 6 Time:4756 ms 7 Memory:31476 kb 8 ****************************************************************/ 9 10 var 11 i,j,k,l,m,n,tot:longint;ch:char; 12 a,b,c,d,e,lef,rig,fix:array[0..1000000] of longint; 13 function max(x,y:longint):longint; 14 begin 15 if x>y then max:=x else max:=Y; 16 end; 17 function min(x,y:longint):longint; 18 begin 19 if x<y then min:=x else min:=y; 20 end; 21 procedure swap(var x,y:longint); 22 var z:longint; 23 begin 24 z:=x;x:=y;y:=z; 25 end; 26 function newp(x:longint):longint; 27 begin 28 inc(tot);newp:=tot; 29 c[tot]:=x;b[tot]:=1; 30 lef[tot]:=0;rig[tot]:=0; 31 fix[tot]:=random(maxlongint); 32 end; 33 procedure rt(var x:longint); 34 var f,l:longint; 35 begin 36 if (x=0) or (lef[x]=0) then exit; 37 b[lef[x]]:=b[x];b[x]:=b[rig[x]]+b[rig[lef[x]]]+1; 38 f:=x;l:=lef[x]; 39 lef[f]:=rig[l]; 40 rig[l]:=f; 41 x:=l; 42 end; 43 procedure lt(var x:longint); 44 var f,r:longint; 45 begin 46 if (x=0) or (rig[x]=0) then exit; 47 b[rig[x]]:=b[x];b[x]:=b[lef[x]]+b[lef[rig[x]]]+1; 48 f:=x;r:=rig[x]; 49 rig[f]:=lef[r]; 50 lef[r]:=f; 51 x:=r; 52 end; 53 procedure ins(var x:longint;y:longint); 54 begin 55 if x=0 then 56 begin 57 x:=newp(y); 58 exit; 59 end; 60 if y<c[x] then 61 begin 62 ins(lef[x],y); 63 b[x]:=b[lef[x]]+b[rig[x]]+1; 64 if fix[lef[x]]<fix[x] then rt(x); 65 end 66 else 67 begin 68 ins(rig[x],y); 69 b[x]:=b[lef[x]]+b[rig[x]]+1; 70 if fix[rig[x]]<fix[x] then lt(x); 71 end; 72 end; 73 procedure del(var x:longint;y:longint); 74 begin 75 if x=0 then exit; 76 if c[x]=y then 77 begin 78 if lef[x]=0 then x:=rig[x] else 79 if rig[x]=0 then x:=lef[x] else 80 if fix[lef[x]]>fix[rig[x]] then 81 begin 82 lt(x); 83 del(lef[x],y); 84 b[x]:=b[lef[x]]+b[rig[x]]+1; 85 end 86 else begin 87 rt(x); 88 del(rig[x],y); 89 b[x]:=b[lef[x]]+b[rig[x]]+1; 90 end; 91 end 92 else if y<c[x] then 93 begin 94 del(lef[x],y); 95 b[x]:=b[lef[x]]+b[rig[x]]+1; 96 end 97 else begin 98 del(rig[x],y); 99 b[x]:=b[rig[x]]+b[lef[x]]+1; 100 end; 101 end; 102 function grank(x,y:longint):longint; 103 begin 104 if x=0 then exit(0); 105 if c[x]>=y then exit(grank(lef[x],y)) else exit(b[lef[x]]+1+grank(rig[x],y)); 106 end; 107 function gmin(x:longint):longint; 108 begin 109 if x=0 then exit(maxlongint); 110 while lef[x]<>0 do x:=lef[x]; 111 exit(c[x]); 112 end; 113 function gmax(x:longint):longint; 114 begin 115 if x=0 then exit(-maxlongint); 116 while rig[x]<>0 do x:=rig[x]; 117 exit(c[x]); 118 end; 119 function getrank(z,x,y,l,r,t:longint):longint; 120 begin 121 if l>r then exit(0); 122 if (x=l) and (y=r) then exit(grank(a[z],t)); 123 exit(getrank(z*2,x,(x+y) div 2,l,min(r,(x+y) div 2),t)+ 124 getrank(z*2+1,(x+y) div 2+1,y,max((x+y) div 2+1,l),r,t)); 125 end; 126 function getmin(z,x,y,l,r:longint):longint; 127 begin 128 if l>r then exit(maxlongint); 129 if (x=l) and (y=r) then exit(gmin(a[z])); 130 exit(min(getmin(z*2,x,(x+y) div 2,l,min(r,(x+y) div 2)), 131 getmin(z*2+1,(x+y) div 2+1,y,max((x+y) div 2+1,l),r))); 132 end; 133 function getmax(z,x,y,l,r:longint):longint; 134 begin 135 if l>r then exit(-maxlongint); 136 if (x=l) and (y=r) then exit(gmax(a[z])); 137 exit(max(getmax(z*2,x,(x+y) div 2,l,min(r,(x+y) div 2)), 138 getmax(z*2+1,(x+y) div 2+1,y,max((x+y) div 2+1,l),r))); 139 end; 140 function rankget(x,y,z:longint):longint; 141 var l,r,m:longint; 142 begin 143 l:=getmin(1,1,n,x,y); 144 r:=getmax(1,1,n,x,y); 145 while l<=r do 146 begin 147 m:=(l+r) div 2; 148 if getrank(1,1,n,x,y,m)<=(z-1) then 149 begin 150 l:=m+1; 151 rankget:=m; 152 end 153 else r:=m-1; 154 end; 155 end; 156 procedure built(z,x,y:longint); 157 begin 158 if x=y then d[x]:=z else 159 begin 160 built(z*2,x,(x+y) div 2); 161 built(z*2+1,(x+y) div 2+1,y); 162 end; 163 a[z]:=0; 164 end; 165 procedure putin(x,y:longint); 166 begin 167 x:=d[x]; 168 while x>0 do 169 begin 170 ins(a[x],y); 171 x:=x div 2; 172 end; 173 end; 174 procedure change(x,y:longint); 175 var z:longint; 176 begin 177 x:=d[x]; 178 z:=c[a[x]]; 179 while x>0 do 180 begin 181 del(a[x],z); 182 ins(a[x],y); 183 x:=x div 2; 184 end; 185 end; 186 begin 187 readln(n,m); 188 built(1,1,n); 189 for i:=1 to n do 190 begin 191 read(j); 192 putin(i,j); 193 end; 194 readln; 195 for i:=1 to m do 196 begin 197 read(ch); 198 case upcase(ch) of 199 'Q':begin 200 readln(j,k,l); 201 writeln(rankget(j,k,l)); 202 end; 203 'C':begin 204 readln(j,k); 205 change(j,k); 206 end; 207 end; 208 209 end; 210 end.