poj主席树裸题
http://poj.org/problem?id=2104
mark一下主席树的写法以及离散化的方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<algorithm> #define M 200005 using namespace std; int tot=0; struct Tree { struct node { int l,r,v; } T[M<<4]; void init(int &p,int l,int r) { p=++tot; T[p].v=0; if(l==r)return; int mid=l+r>>1; init(T[p].l,l,mid); init(T[p].r,mid+1,r); } void insert(int &p,int l,int r,int x,int pre) { p=++tot; T[p]=T[pre]; T[p].v++; if(l==r)return; int mid=l+r>>1; if(x<=mid)insert(T[p].l,l,mid,x,T[pre].l); else insert(T[p].r,mid+1,r,x,T[pre].r); } int query(int id1,int id2,int l,int r,int k) { if(l==r)return l; int v1=T[T[id1].l].v; int v2=T[T[id2].l].v; int v=v2-v1,mid=l+r>>1; if(k<=v)return query(T[id1].l,T[id2].l,l,mid,k); return query(T[id1].r,T[id2].r,mid+1,r,k-v); } } CT; int root[M],rt; int team1[M],team2[M],team3[M]; int main() { int n,m,a,b,c; scanf("%d %d",&n,&m); for(int i=1; i<=n; i++)scanf("%d",&team1[i]),team2[i]=team1[i]; sort(team2+1,team2+1+n); int size=unique(team2+1,team2+1+n)-team2-1; CT.init(rt,1,size); root[0]=rt; for(int i=1; i<=n; i++) { int now=lower_bound(team2+1,team2+1+n,team1[i])-team2; CT.insert(root[i],1,size,now,root[i-1]); team3[now]=team1[i]; } for(int i=1; i<=m; i++) { scanf("%d %d %d",&a,&b,&c); printf("%d ",team3[CT.query(root[a-1],root[b],1,size,c)]); } return 0; }