<a target=_blank href="http://poj.org/problem?id=2104" target="_blank"><span style="font-size:24px;">POJ 2104</span></a>
POJ 2761
做法好多,主席树,划分树,离线处理(曼哈顿最小生成树?)+BST(Treap or Splay or SBT),貌似分治+BIT也可以,不过懒得搞了。
以后复习模板时用得上。
主席树:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=100010; struct Node{ int l,r,w; }tr[N*20]; int a[N],b[N],rank[N],root[N],sz; void ins(int &i,int l,int r,int x){ tr[++sz]=tr[i];i=sz; tr[i].w++; if(l==r)return; int m=l+r>>1; if(x<=m)ins(tr[i].l,l,m,x); else ins(tr[i].r,m+1,r,x); } int query(int i,int j,int l,int r,int k){ if(l==r)return l; int m=l+r>>1; int tmp=tr[tr[j].l].w-tr[tr[i].l].w; if(k<=tmp)return query(tr[i].l,tr[j].l,l,m,k); else return query(tr[i].r,tr[j].r,m+1,r,k-tmp); } inline bool cmp(int i,int j){ return a[i]<a[j]; } int main(){ int n,m;scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]);rank[i]=i; } sort(rank+1,rank+1+n,cmp); for(int i=1;i<=n;i++)b[rank[i]]=i; for(int i=1;i<=n;i++){ root[i]=root[i-1]; ins(root[i],1,n,b[i]); } int x,y,k; while(m--){ scanf("%d%d%d",&x,&y,&k); int tmp=query(root[x-1],root[y],1,n,k); printf("%d\n",a[rank[tmp]]); } return 0; }