HDU 2852 KiKi's K-Number

权值线段树

#include <cstdio> 

#include <cstring>

const int N=200000,M=220000;

int k,q,x,y,sum[M<<2],n;

char c;

void up(int x){sum[x]=sum[x<<1]+sum[x<<1|1];}

void update(int t,int num,int l,int r,int x){

    if(l==r){

        if(sum[x]+num<0)puts("No Elment!");

        else sum[x]+=num;return;

    }

    int mid=(l+r)>>1;

    if(t<=mid)update(t,num,l,mid,x<<1);

    else update(t,num,mid+1,r,x<<1|1);

    up(x);

} 

int query(int L,int R,int l,int r,int x){

    if(L<=l&&r<=R)return(sum[x]);

    int mid=(l+r)>>1,tmp=0;

    if(L<=mid)tmp+=query(L,R,l,mid,x<<1);

    if(mid<R)tmp+=query(L,R,mid+1,r,x<<1|1);

    return tmp;

}

int find(int k,int l,int r,int x){

    int mid=(l+r)>>1,tmp=sum[x<<1|1];

    if(l==r)return l;

    if (k<=tmp) return find(k,mid+1,r,x<<1|1);

    else return find(k-tmp,l,mid,x<<1);

}

int scan(int &x){

    while(c=getchar(),c<'0'||c>'9');x=c-'0';

    while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';

}

int main(){

    while(~scanf("%d",&n)){

        for(int i=0;i<(M<<2);i++)sum[i]=0;

        while(n--){

            scan(q);

            if(q==0){scan(x),update(x,1,1,N,1);}

            if(q==1){scan(x),update(x,-1,1,N,1);}

            if(q==2){

                scan(x),scan(k);

                if((y=query(x+1,N,1,N,1))<k)puts("Not Find!");

                else printf("%d\n",find(y-k+1,1,N,1));

            }

        } 

    }

    return 0;

}

分块

#include <cstdio>

int i,j,x,y,k,op,m,n,p[1000],pos[100005],a[100005],block,st[100005],en[100005];

int main(){

    int size=0;

    while(size*size<=100000)size++;

    for(int i=1;i<=100000;i++)pos[i]=(i-1)/size+1;

    for(block=pos[100000],i=1;i<=block;i++)en[i-1]=(st[i]=size*(i-1)+1)-1;en[block]=100000;

    while(~scanf("%d",&n)){

        for(int i=1;i<1000;i++)p[i]=0;

        for(int i=1;i<=100000;i++)a[i]=0;

        while(n--){

            scanf("%d",&op);

            if(op==0){scanf("%d",&x);a[x]++;p[pos[x]]++;}

            if(op==1){scanf("%d",&x);if(!a[x])puts("No Elment!");else{a[x]--;p[pos[x]]--;}}

            if(op==2){

                scanf("%d%d",&x,&k);

                for(i=x+1;i<=en[pos[x+1]];i++){k-=a[i];if(k<=0){printf("%d\n",i);break;}}

                if(k>0){

                    for(i=pos[x+1]+1;i<=block;i++){k-=p[i];if(k<=0)break;}

                    if(k>0)puts("Not Find!");

                    else for(k+=p[i],j=st[i];j<=en[i];j++){k-=a[j];if(k<=0){printf("%d\n",j);break;}}

                }

            }

        }

    }return 0;

}

你可能感兴趣的:(number)