题意就是区间第k大……
题解:
前段时间用主席树搞掉了……
如今看到划分树,是在想来写一遍,结果18号对着学长的代码调了一上午连样例都没过,好桑心……
今天在做NOI2010超级钢琴,忽然发现用划分树很直观,果断决定再战划分树
对着网上的c++代码抄了一遍,A了,可是这编程复杂度有点高,忽然又看见盾哥的代码
很简短,和我原先的代码差不多,他怎么能A了呢……(后来发现区间第k小,我却写的第k大……sb啊)
考虑到盾哥的程序用到了离散化,因此没有考虑存在两个数相等的情况,这样就使代码减少很多
我报着试一试的心态把我认为肯定对的代码随机生成了几组大数据和盾哥的程序对拍,然后就对上了
好的,以后就用盾哥的程序
代码:
c++翻译来的:
1 var s,t:array[0..20,0..200000] of longint; 2 a,rk:array[0..200000] of longint; 3 i,n,m,x,y,k,j:longint; 4 procedure sort(l,r:longint); 5 var i,j,m,temp:longint; 6 begin 7 i:=l;j:=r;m:=a[(i+j)>>1]; 8 repeat 9 while a[i]<m do inc(i); 10 while a[j]>m do dec(j); 11 if i<=j then 12 begin 13 temp:=a[i];a[i]:=a[j];a[j]:=temp; 14 inc(i);dec(j); 15 end; 16 until i>j; 17 if i<r then sort(i,r); 18 if j>l then sort(l,j); 19 end; 20 procedure init; 21 begin 22 readln(n,m); 23 for i:=1 to n do read(a[i]);t[0]:=a; 24 sort(1,n); 25 end; 26 procedure build(h,l,r:longint); 27 var mid,i,lp,rp,lm:longint; 28 begin 29 mid:=(l+r)>>1;lm:=mid-l+1;lp:=l;rp:=mid+1; 30 for i:=l to mid do 31 if a[i]<a[mid] then dec(lm); 32 for i:=l to r do 33 begin 34 if i=l then s[h,i]:=0 else s[h,i]:=s[h,i-1]; 35 if t[h,i]=a[mid] then 36 begin 37 if lm<>0 then 38 begin 39 dec(lm);inc(s[h,i]);t[h+1,lp]:=t[h,i];inc(lp); 40 end 41 else begin t[h+1,rp]:=t[h,i];inc(rp);end; 42 end 43 else 44 if t[h,i]<a[mid] then begin inc(s[h,i]);t[h+1,lp]:=t[h,i];inc(lp);end 45 else begin t[h+1,rp]:=t[h,i];inc(rp);end; 46 end; 47 if l=r then exit; 48 build(h+1,l,mid); 49 build(h+1,mid+1,r); 50 end; 51 function find(h,l,r,x,y,k:longint):longint; 52 var mid,ll,rr:longint; 53 begin 54 if l=r then exit(t[h,l]); 55 mid:=(l+r)>>1; 56 if l=x then ll:=0 else ll:=s[h,x-1];rr:=s[h,y]-ll; 57 if rr>=k then exit(find(h+1,l,mid,l+ll,l+ll+rr-1,k)) 58 else exit(find(h+1,mid+1,r,mid+1+x-l-ll,mid+1+y-l-ll-rr,k-rr)); 59 end; 60 procedure main; 61 begin 62 build(0,1,n); 63 for i:=1 to m do 64 begin 65 readln(x,y,k); 66 writeln(find(0,1,n,x,y,k)); 67 end; 68 end; 69 begin 70 init; 71 main; 72 end.