zoukankan      html  css  js  c++  java
  • hdu 4217 树状数组+二分搜索

    Problem: http://acm.hdu.edu.cn/showproblem.php?pid=4217

    给定1~n的n个数

    依次求第ki小的数 删除该数 再求剩下的数中第ki+1小的数 删除...

    求所有删除的数的和

    用树状数组bit[]:bit[k](这里的bit[k]不是bit[k]本身的值,详见代码中find(k))表示小于等于 k 的数的个数

    用二分搜索 搜索第ki大的数

    #include<cstdio>
    const int MAXN=270000;
    int bit[MAXN];
    int find(int k){//查找小于等于k的数的个数 
        int ret=0;
        while(k>0){
            ret+=bit[k];
            k-=k&-k;
        }
        return ret;
    }
    int work(int k,int n){
        int L=1,R=n;
        while(L<R){//二分搜索第k大的值 
            int M=(L+R)>>1;
            if(k>find(M))L=M+1;
            else R=M;
        }
        while(R<=n){//删除第k大的值 在树状数组中的形式为比k大的数 的bit[]-1 
            bit[R]--;
            R+=R&-R;
        }
        return L;
    }
    int main()
    {
        int t,n,k,ki;
        scanf("%d",&t);
        for(int Case=1;Case<=t;Case++){
            scanf("%d%d",&n,&k);
            for(int i=1;i<=n;i++)bit[i]=i&-i;//树状数组实现 
            long long ans=0;
            for(int i=0;i<k;i++){
                scanf("%d",&ki);
                ans+=work(ki,n);
            }
            printf("Case %d: %I64d
    ",Case,ans);
        }
        return 0;
    }
    View Code

    想想 此题线段树、平衡数应该都可做

  • 相关阅读:
    本学期3个sprint的团队贡献分
    sprint3个人总结
    12.17第九天
    阶段二总结
    sprint 1 总结
    冲刺一
    课程设计团队信息
    学习进度表
    Sprint3总结
    Res_Orders_02
  • 原文地址:https://www.cnblogs.com/cshhr/p/3543516.html
Copyright © 2011-2022 走看看