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.