K-th Number(poj 2104)

题意:静态第K大

#include<cstdio>
#include<iostream>
#include<cstring>
#define N 200010
#define inf 1000000000
using namespace std;
int n,m,num,tmp[N],ans[N],sum[N];
struct node{
    int x,y,k,s,tp,cur;
};node a[N],q1[N],q2[N];
void modify(int x,int v){
    while(x<=n){
        sum[x]+=v;
        x+=x&(-x);
    }
}
int query(int x){
    int tot=0;
    while(x){
        tot+=sum[x];
        x-=x&(-x);
    }
    return tot;
}
void solve(int head,int tail,int l,int r){
    if(head>tail)return;
    if(l==r){
        for(int i=head;i<=tail;i++)
            if(a[i].tp==2)ans[a[i].s]=l;
        return;
    }
    int mid=l+r>>1;
    for(int i=head;i<=tail;i++){
        if(a[i].tp==1&&a[i].y<=mid) modify(a[i].x,1);
        if(a[i].tp==2) tmp[i]=query(a[i].y)-query(a[i].x-1);
    }
    for(int i=head;i<=tail;i++)
        if(a[i].tp==1&&a[i].y<=mid) modify(a[i].x,-1);
    int l1=0,l2=0;
    for(int i=head;i<=tail;i++){
        if(a[i].tp==2){
            if(a[i].cur+tmp[i]>=a[i].k) q1[++l1]=a[i];
            else a[i].cur+=tmp[i],q2[++l2]=a[i];
        }
        else {
            if(a[i].y<=mid) q1[++l1]=a[i];
            else q2[++l2]=a[i];
        }
    }
    for(int i=1;i<=l1;i++)a[head+i-1]=q1[i];
    for(int i=1;i<=l2;i++)a[head+l1+i-1]=q2[i];
    solve(head,head+l1-1,l,mid);
    solve(head+l1,tail,mid+1,r);
}
void work(){
    for(int i=1;i<=n;i++){
        int x;scanf("%d",&x);
        a[++num].x=i;a[num].y=x;a[num].s=0;a[num].tp=1;
    }
    for(int i=1;i<=m;i++){
        int x,y,k;scanf("%d%d%d",&x,&y,&k);
        a[++num].x=x;a[num].y=y;a[num].k=k;a[num].s=i;a[num].tp=2;
    }
    solve(1,num,-inf,inf);
    for(int i=1;i<=m;i++)
        printf("%d\n",ans[i]);
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(tmp,0,sizeof(tmp));
        memset(sum,0,sizeof(sum));
        memset(ans,0,sizeof(ans));
        memset(a,0,sizeof(a));
        num=0;
        work();
    }
    return 0;
}

 

posted @ 2017-02-21 22:08  karles~  阅读(128)  评论(0编辑  收藏  举报