1. 程式人生 > >POJ2104:K-th Number——題解

POJ2104:K-th Number——題解

nbsp dash str sdi targe ash sum queue sin

http://poj.org/problem?id=2104

題目大意:求區間第k小。

——————————————————————————

主席樹板子題。

……我看了半天現在還是一知半解的狀態所以應該不會出講解了。

#include<cstdio>
#include
<queue> #include<cctype> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; const int N=100001; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch==-;ch=getchar();} while(isdigit(ch))X=(X<<3
)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } struct tree{ int l; int r; int sum; }tr[N*20]; int a[N],b[N],rt[N],n,m,q,pool; inline void insert(int &y,int &x,int l,int r,int p){ tr[x=++pool]=tr[y]; tr[x].sum++; if(l==r)return; int mid=(l+r)>>1
; if(p<=mid)insert(tr[y].l,tr[x].l,l,mid,p); else insert(tr[y].r,tr[x].r,mid+1,r,p); return; } inline int query(int nl,int nr,int l,int r,int k){ if(l==r)return l; int delta=tr[tr[nr].l].sum-tr[tr[nl].l].sum; int mid=(l+r)>>1; if(delta>=k)return query(tr[nl].l,tr[nr].l,l,mid,k); else return query(tr[nl].r,tr[nr].r,mid+1,r,k-delta); } inline void LSH(){ m=n; sort(b+1,b+m+1); m=unique(b+1,b+m+1)-b-1; for(int i=1;i<=n;i++){ a[i]=lower_bound(b+1,b+m+1,a[i])-b; } return; } int main(){ n=read(); q=read(); for(int i=1;i<=n;i++)a[i]=b[i]=read(); LSH(); for(int i=1;i<=n;i++)insert(rt[i-1],rt[i],1,m,a[i]); for(int i=1;i<=q;i++){ int l=read(),r=read(),k=read(); printf("%d\n",b[query(rt[l-1],rt[r],1,m,k)]); } return 0; }

POJ2104:K-th Number——題解