Codefroces 1362B Johnny and Grandmaster (贪心+hash)
Posted wrjlinkkkkkk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}
以上是关于Codefroces 1362B Johnny and Grandmaster (贪心+hash)的主要内容,如果未能解决你的问题,请参考以下文章
codefroces Round #201.a--Difference Row
codefroces 946G Almost Increasing Array
Codefroces 1245 F. Daniel and Spring Cleaning