题目链接:https://codeforces.com/contest/1362/problem/E
题目大意:
多样例:一个n和p,下面输入n个数k[i],每个数代表p^k[i],把这些数分成两组。使他们的和的差值最小。输出这个差值mod 1e9+7。
思路一:把k[i]从大到小排序,如果k[i]为偶数,这个各种分配一半。如果为奇,那么一个就分配多了一个。我们希望用后面的 k[i]去弥补这个差值。模拟这个过程就可以了。
思路二:直接用哈希暴力搞过去。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const LL mod=1000000007;
LL k[1000005];
LL quick_pow(LL a, LL b){
if(a==0){
return 0;
}
LL ans=1;
while(b){
if(b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int main(){
int t; scanf("%d", &t);
while(t--){
LL n, p; scanf("%lld%lld", &n, &p);
for(int i=1; i<=n; i++){
scanf("%lld", &k[i]);
}
sort(k+1, k+1+n, greater<int>() );
if(n%2==0&&p==1){
printf("0\n");
continue;
}
else if(p==1){
printf("1\n");
continue;
}
LL pos=0, A=0, pos2=0;
for(int i=1; i<=n; ){
LL x=k[i], r=i+1, y=1;
while(k[r]==x&&r<=n){
r++; y++;
}
LL L=pos;
int fg=0;
for(int k=1; k<=A-x&&pos&&p!=1; k++){
L*=p;
if(L>n-i+1){
fg=1;
}
}
if(fg==0)
pos=L;
if(fg){
for(LL pos=i; pos<=n; pos++){
LL x=k[pos];
pos2+=(quick_pow(p, x))%mod; pos2%=mod;
}
break;
}
LL c=y;
if(pos>=c){
pos-=c; A=x;
}
else{
c-=pos;
if(c%2) pos=1, A=x;
else pos=0;
}
i+=y;
}
printf("%lld\n", ((pos*quick_pow(p, A))%mod-pos2+mod)%mod);
}
return 0;
}
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const LL mod1=1000000007;
const LL mod2=10995514;
const LL mod3=200000011;
LL k[1000005];
LL quick_pow(LL a, LL b, LL mod){
if(a==0){
return 0;
}
LL ans=1;
while(b){
if(b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int main(){
int t; scanf("%d", &t);
while(t--){
LL n, p; scanf("%lld%lld", &n, &p);
for(int i=1; i<=n; i++){
scanf("%lld", &k[i]);
}
sort(k+1, k+1+n, greater<int>() );
LL ans1=0, ans2=0, ans3=0, sig=0;
for(int i=1; i<=n; i++){
sig=-1;
if(ans1==0&&ans2==0&&ans3==0){
sig=1;
}
ans1=(ans1+quick_pow(p, k[i], mod1)*sig+mod1)%mod1;
ans2=(ans2+quick_pow(p, k[i], mod2)*sig+mod2)%mod2;
ans3=(ans3+quick_pow(p, k[i], mod3)*sig+mod3)%mod3;
}
cout<<ans1<<endl;
}
return 0;
}
京公网安备 11010502036488号