主席树 又称函数式线段树,又称可持久化线段树……缺点是内存有点儿大……
1 type node1=record 2 l,r,sum:longint; 3 end; 4 node2=record 5 x,idx:longint; 6 end; 7 var q,i,j,k,tot,n,m:longint; 8 a:array[0..500000] of node2; 9 rank,root:array[0..500000] of longint; 10 t:array[0..5000000] of node1; 11 procedure qsort(h,l:longint); 12 var i,j,m:longint; 13 temp:node2; 14 begin 15 i:=h;j:=l;m:=a[(i+j)>>1].x; 16 repeat 17 while a[i].x<m do inc(i); 18 while a[j].x>m do dec(j); 19 if i<=j then 20 begin 21 temp:=a[i];a[i]:=a[j];a[j]:=temp; 22 inc(i);dec(j); 23 end; 24 until i>j; 25 if i<l then qsort(i,l); 26 if j>h then qsort(h,j); 27 end; 28 procedure insert(var x:longint;num,l,r:longint); 29 var mid:longint; 30 begin 31 t[tot]:=t[x]; 32 x:=tot; 33 inc(tot); 34 inc(t[x].sum); 35 if l=r then exit; 36 mid:=(l+r)>>1; 37 if num<=mid then insert(t[x].l,num,l,mid) 38 else insert(t[x].r,num,mid+1,r); 39 end; 40 function query(i,j,k,l,r:longint):longint; 41 var mid,tmp:longint; 42 begin 43 if l=r then exit(l); 44 tmp:=t[t[j].l].sum-t[t[i].l].sum; 45 mid:=(l+r)>>1; 46 if k<=tmp then exit(query(t[i].l,t[j].l,k,l,mid)) 47 else exit(query(t[i].r,t[j].r,k-tmp,mid+1,r)); 48 end; 49 procedure main; 50 begin 51 t[0].l:=0;t[0].r:=0;t[0].sum:=0;root[0]:=0; 52 readln(n,m); 53 for i:=1 to n do begin read(a[i].x);a[i].idx:=i;end; 54 qsort(1,n); 55 tot:=1; 56 for i:=1 to n do rank[a[i].idx]:=i; 57 for i:=1 to n do 58 begin 59 root[i]:=root[i-1]; 60 insert(root[i],rank[i],1,n); 61 end; 62 for q:=1 to m do 63 begin 64 readln(i,j,k); 65 writeln(a[query(root[i-1],root[j],k,1,n)].x); 66 end; 67 end; 68 begin 69 main; 70 end.
poj2014 不带修改区间第k大树,布布扣,bubuko.com
原文地址:http://www.cnblogs.com/zyfzyf/p/3775842.html