POJ

来源:互联网 发布:拉比 婴儿床 知乎 编辑:程序博客网 时间:2024/06/06 01:42

题目:给你一个n个数的序列,m个询问,每次询问为i,j,k,问区间[i,j]中的数按升序排序后,第k个数是什么

思路:CDQ分治,整体二分答案

代码:

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<algorithm>#include<ctime>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<list>#include<numeric>using namespace std;#define LL long long#define ULL unsigned long long#define INF 0x3f3f3f3f#define mm(a,b) memset(a,b,sizeof(a))#define PP puts("*********************");template<class T> T f_abs(T a){ return a > 0 ? a : -a; }template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}// 0x3f3f3f3f3f3f3f3f//0x3f3f3f3fconst int maxn=110050;struct Query{    int x,y,k,pos,type;    Query(int _x,int _y,int _k,int _pos,int _type):x(_x),y(_y),k(_k),pos(_pos),type(_type){}    Query(){}}q[maxn],q1[maxn],q2[maxn];struct BIT{    int n,b[maxn];    void init(int _n){        n=_n;        mm(b,0);    }    void add(int i,int val){        for(;i<=n;i+=i&(-i))            b[i]+=val;    }    int sum(int i){        int ret=0;        for(;i>0;i-=i&(-i))            ret+=b[i];        return ret;    }}bit;int arr[maxn],ans[maxn];void solve(int L,int R,int l,int r){    if(L>R) return;    if(l==r){        for(int i=L;i<=R;i++)            if(q[i].type==2)                ans[q[i].pos]=l;        return;    }    int mid=(l+r)>>1;    int sz1=0,sz2=0;    for(int i=L;i<=R;i++){        if(q[i].type==1){            if(q[i].x<=mid){                bit.add(q[i].pos,1);                q1[sz1++]=q[i];            }            else                q2[sz2++]=q[i];        }        else{            int res=bit.sum(q[i].y)-bit.sum(q[i].x-1);            if(res>=q[i].k) q1[sz1++]=q[i];            else{                q[i].k-=res;                q2[sz2++]=q[i];            }        }    }    for(int i=0;i<sz1;i++)//清空        if(q1[i].type==1)            bit.add(q1[i].pos,-1);    memcpy(q+L,q1,sz1*sizeof(Query));    memcpy(q+L+sz1,q2,sz2*sizeof(Query));    solve(L,L+sz1-1,l,mid);    solve(L+sz1,R,mid+1,r);}int main(){//    freopen("D:\\input.txt","r",stdin);//    freopen("D:\\output.txt","w",stdout);    int n,m,x,y,k;    while(~scanf("%d%d",&n,&m)){        bit.init(n);        int idx=0;        for(int i=1;i<=n;i++){            scanf("%d",&arr[i]);            q[++idx]=Query(arr[i],1,1,i,1);        }        for(int i=1;i<=m;i++){            scanf("%d%d%d",&x,&y,&k);            q[++idx]=Query(x,y,k,i,2);        }        solve(1,idx,-INF,INF);        for(int i=1;i<=m;i++)            printf("%d\n",ans[i]);    }    return 0;}