主席树 又称函数式线段树,又称可持久化线段树……缺点是内存有点儿大……
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
时间: 2024-11-03 21:19:34