link/cut tree
[kudsource.git] / POJ / 2104.partitiontree.cc
blob285b69867fdbbb8f38e6541848f3a3554275f156
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
5 using namespace std;
7 const int maxn=100001;
9 int sorted[maxn];
10 int toLeft[20][maxn],val[20][maxn];
12 void build(int l, int r, int d, int k)
13 //d:dep, k:order
15 if (l==r) return;
16 int mid=l+r>>1,lsame=mid-l+1;
17 for (int i=l; i<=r; ++i) if (val[d][i]<sorted[mid]) --lsame;
18 int lpos=l,rpos=mid+1,same=0;
19 for (int i=l; i<=r; ++i)
21 if (i==l) toLeft[d][i]=0; else toLeft[d][i]=toLeft[d][i-1];
22 if (val[d][i]<sorted[mid])
24 ++toLeft[d][i];
25 val[d+1][lpos++]=val[d][i];
27 else if (val[d][i]>sorted[mid]) val[d+1][rpos++]=val[d][i];
28 else
30 if (same<lsame)
32 ++same,++toLeft[d][i];
33 val[d+1][lpos++]=val[d][i];
35 else val[d+1][rpos++]=val[d][i];
38 build(l,mid,d+1,k<<1);
39 build(mid+1,r,d+1,k<<1|1);
42 int query(int l, int r, int p, int q, int rank, int d, int k)
44 if (l==r) return val[d][l];
45 int s,ss;
46 if (l==p) s=toLeft[d][r],ss=0; else
47 s=toLeft[d][r]-toLeft[d][l-1],ss=toLeft[d][l-1];
48 int m=p+q>>1;
49 if (s>=rank)
51 int newl=p+ss,newr=p+ss+s-1;
52 return query(newl,newr,p,m,rank,d+1,k<<1);
54 else
56 int bb=l-p-ss,b=r-l+1-s;
57 int newl=m+bb+1,newr=m+bb+b;
58 return query(newl,newr,m+1,q,rank-s,d+1,k<<1|1);
62 int main()
64 int n,m;
65 scanf("%d%d",&n,&m);
66 for (int i=1; i<=n; ++i) scanf("%d",&sorted[i]);
67 memcpy(val[0],sorted,sizeof(sorted));
68 sort(sorted+1,sorted+n+1);
69 build(1,n,0,1);
70 while (m--)
72 int l,r,k;
73 scanf("%d%d%d",&l,&r,&k);
74 printf("%d\n",query(l,r,1,n,k,0,1));
76 return 0;