HDU 2852 KiKi's K-Number【 树状数组 二分 】

来源:互联网 发布:qq显示ip软件 编辑:程序博客网 时间:2024/05/19 00:52
题意:给出m个操作,
0:是增加一个数,add(x,1)
1:是删除一个指定的数,这个是看sum(x) - sum(x-1)是否为0,为0的话则不存在,不为0的话,则add(x,-1)

2:是查询比x大的数中第k大的数


反思:做的时候没想到二分,长教训了,以后一定得注意查找的费时。不过这题也要注意二分的姿势。以后我做题得拿什么了。

上代码:

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;int ans[100010];int n;int maxn;int getf(int x){    return x&(-x);}void add(int x,int d){    while(x<=100000)    {        ans[x] += d;        x += getf(x);    }    return ;}int getsum(int x){    int sum = 0;    while(x>0)    {        sum += ans[x];        x -= getf(x);    }    return sum;}int ex[100010]; // 不仅有标记的作用还可以顺便统计这个数的个数int main(){    while(scanf("%d", &n) != EOF)    {        memset(ans, 0, sizeof(ans));        memset(ex , 0, sizeof(ex));        int p;        int maxn = -1;        for(int i=1; i<=n; i++)        {            scanf("%d", &p);            if(p==0)            {                int a;                scanf("%d", &a);                add(a,1);                ex[a]++;            }            if(p==1)            {                int a;                scanf("%d", &a);                if(ex[a]==0){printf("No Elment!\n");continue;}                add(a,-1);                ex[a]--;            }            if(p==2)            {                int a,k;                scanf("%d %d",&a, &k);                // 已下为二分                int flag = -1;                int sum_a = getsum(a)+k;                int left = a+1; int right = 100001;                        while(left<=right)                        {                           int mid = (left+right) / 2;                           int qq = getsum(mid);                           if(qq==sum_a)                           {                               if(ex[mid]!=0){flag=mid;break;}                               right = mid - 1;                           }                           else if(qq<sum_a)                           {                               left = mid +1;                           }else if(qq>sum_a)                           {                               if(qq-ex[mid]+1<=sum_a)                               {                                   if(ex[mid]!=0){flag=mid;break;}                                }                               right = mid - 1;                           }                        }                  if(flag!=-1)                  {                      printf("%d\n",flag);                  }                  else                  {                      printf("Not Find!\n");                  }             }        }   }    return 0;}
水波。

阅读全文
0 0
原创粉丝点击