zoukankan      html  css  js  c++  java
  • Codefroces 1362B Johnny and Grandmaster (贪心+hash)

    题意

    给你n和p,还有n个p的指数,问你怎么分可以让AB两个集合的和的差最小,n,p<=1e6,答案需要模1e9+7

    思路

    分成两组的问题参考51nod2334,朴素方法是背包或者dfs
    但这题是在p进制下的,可以想到贪心的策略:
    从大到小进行分配,每次将(p^{a[i]})分配到当前的和比较小的集合当中
    我们不妨令等于的时候都放到B集合里,对答案没有影响
    由于是从大到小,根据p进制下的性质,在操作的过程中会恒有(Sum_Aleq Sum_B)
    由于答案为ans=(Sum_B-Sum_A)
    我们只需要根据ans是否为零来判断当前指数对答案是正贡献还是负贡献即可
    因为判断的是ans的真值是否为零,而我们维护的是模意义下的值,所以需要通过双hash判断真值

    代码

    int n,m;
    int a[maxn];
    int fp(int a, int n, int mod){
        int ans = 1;
        while(n){
            if(n&1)ans=1ll*ans*a%mod;
            n>>=1;
            a=1ll*a*a%mod;
        }
        return ans;
    }
    
    int p,mx;
    int main() {
        int t;
        scanf("%d", &t);
        while(t--){
            scanf("%d %d",&n,&m);
            for(int i = 1; i <= n; i++){
                scanf("%d", &a[i]);
            }
            sort(a+1,a+1+n);
            int c = 19270817;
            int ans1 = 0, ans2 = 0;
            for(int i = n; i >= 1; i--){
                if(!ans1&&!ans2){
                    ans1=(1ll*ans1+fp(m,a[i],mod))%mod;
                    ans2=(1ll*ans2+fp(m,a[i],c))%c;
                }
                else{
                    ans1=(1ll*ans1-fp(m,a[i],mod)+mod)%mod;
                    ans2=(1ll*ans2-fp(m,a[i],c)+c)%c;
                }
            }
            printf("%d
    ",ans1);
        }
        return 0;
    }
    
  • 相关阅读:
    5月29日实验报告
    实验报告(2019年4月30日)下半部分
    实验报告(2019年4月31日)
    实验报告(2019年4月17日)
    第五章 循环结构课后反思
    实验报告(2019年4月3日)
    第一次实验报告
    503小组第三章编程作业
    第九章 结构体与共用体
    第八章 指针实验
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/13048895.html
Copyright © 2011-2022 走看看