HDU 2852 KiKi's K-Number (树状数组+二分)

来源:互联网 发布:java中的垃圾回收机制 编辑:程序博客网 时间:2024/06/05 02:41

题意:

给出一些操作:

0 x 在数组中加入一个数x

1 x 在数组中去掉一个数x

2 a k 在数组中查询比a大的第k小数


分析:

首先看到题目的数据范围 e<100000 ,发现数组完全可以存下,那么就好办了,一个萝卜一个坑~

对于0 1 操作,直接加入数组中计数

对于2操作,二分查询比a大的区间的第k小数,用树状数组或者线段树辅助区间查询

目测整体二分也可以做,但是代码量太大,容易出错,不推介


#include<cstring>#include<string>#include<iostream>#include<queue>#include<cstdio>#include<algorithm>#include<map>#include<cstdlib>#include<cmath>#include<vector>//#pragma comment(linker, "/STACK:1024000000,1024000000");using namespace std;#define INF 0x3f3f3f3fint n;int c[100005];inline int lowbit(int x){    return x&-x;}inline void update(int x,int val){    for(; x<=100000; x+=lowbit(x)) c[x]+=val;}inline int query(int x){    int  sum=0;    for(; x>0; x-=lowbit(x)) sum+=c[x];    return sum;}void Find(int k,int val){    int l=val,r=100000;    while(l<=r)    {        int mid=(l+r)/2;        if(query(mid)-query(val)<k) l=mid+1;        else r=mid-1;    }    if(query(l-1)-query(val)>=k) printf("%d\n",l-1);    else printf("%d\n",l);}int main(){    while(scanf("%d",&n)!=EOF)    {        memset(c,0,sizeof c);        for(int i=1; i<=n; i++)        {            int op;            scanf("%d",&op);            if(!op)            {                int x;                scanf("%d",&x);                update(x,1);            }            else if(op==1)            {                int x;                scanf("%d",&x);                if(query(x)-query(x-1)==0) printf("No Elment!\n");                else update(x,-1);            }            else            {                int val,k;                scanf("%d%d",&val,&k);                if(query(100000)-query(val)<k) printf("Not Find!\n");                else Find(k,val);            }        }    }    return 0;}


0 0
原创粉丝点击