[POJ2104]K-th Number(整体二分)
可以整体二分求,当然主席树也可以
Code
#include <cstdio> #include <algorithm> #define lowbit(x) ((x)&(-x)) #define N 100010 using namespace std; const int Inf=1e9; struct node{ int x,id; friend bool operator <(node a,node b){ return a.x<b.x; } }A[N]; struct que{ int id,x,y,k,cnt; }q[N],tmp[N]; int n,m,Ans[N],sum[N]; inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void calc(int l,int r,int ll,int mid){ int L=1,R=n,M; for(;L<R;){ M=(L+R)>>1; if(A[M].x>=ll) R=M; else L=M+1; } for(int i=R;i<=n&&A[i].x<=mid;++i) for(int j=A[i].id;j<=n;j+=lowbit(j)) ++sum[j]; for(int i=l;i<=r;++i){ q[i].cnt=0; for(int j=q[i].y;j;j-=lowbit(j)) q[i].cnt+=sum[j]; for(int j=q[i].x-1;j;j-=lowbit(j)) q[i].cnt-=sum[j]; } for(int i=R;i<=n&&A[i].x<=mid;++i) for(int j=A[i].id;j<=n;j+=lowbit(j)) --sum[j]; } inline void slove(int l,int r,int L,int R){ if(L==R){ for(int i=l;i<=r;++i) Ans[q[i].id]=L; return; } int mid=(L+R)>>1; calc(l,r,L,mid); int ta=l,tb=r; for(int i=l;i<=r;++i) if(q[i].cnt>=q[i].k) tmp[ta++]=q[i]; else q[i].k-=q[i].cnt,tmp[tb--]=q[i]; for(int i=l;i<=r;++i) q[i]=tmp[i]; if(ta!=l) slove(l,ta-1,L,mid); if(tb!=r) slove(tb+1,r,mid+1,R); } int main(){ n=read(),m=read(); for(int i=1;i<=n;++i) A[A[i].id=i].x=read(); sort(A+1,A+n+1); for(int i=1;i<=m;++i) q[q[i].id=i].x=read(),q[i].y=read(),q[i].k=read(); slove(1,m,-Inf,Inf); for(int i=1;i<=m;++i) printf("%d\n",Ans[i]); return 0; }