B. Johnny and Grandmaster

原题链接:https://codeforc.es/problemset/problem/1361/B

题意:给你n个k求把pk分成两组数和的最小差值对1e9+7取余。

题解:运用贪心的思想取最大的数减去次大的数(先对数组按照降序排序),判断是否存在等于0的情况,如果存在那么最小差值为剩下数的和,如果不存在则答案为最大数减去其他数的和。(不存在小于0的情况)

坑点:1.不能用pow求幂(会超时),需要构造快速幂函数。

          2.需要开另一个mod防止出现差值为1e9+7b倍数时产生的误差。

          3.输入输出要用scanf 和printf 否则会超时。

Ac代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod1=1e9+7;
const ll mod2=0x3f3f3f3f;
const ll maxn=1e6+5;
ll a[maxn];
bool cmp(ll a,ll b){  //降序;
	return a>b;
}
ll fastpow(ll a,ll n,ll m){  //快速幂;
	ll base=a;
	ll res=1;
	while(n){
		if(n&1){
			res=(base*res)%m;
		}
		base=(base*base)%m;
		n>>=1;
	}
	return res;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
    	ll n,p;
    	scanf("%lld%lld",&n,&p);
        for(ll  i=0;i<n;i++) scanf("%lld",&a[i]);
       	sort(a,a+n,cmp);  //排序;
        ll cnt1=0,cnt2=0;
        for(ll i=0;i<n;i++){
        	if(cnt1==0&&cnt2==0){  
               cnt1=(cnt1+fastpow(p,a[i],mod1))%mod1    //防止cnt1%mod1==0对答案造成的影响;
               cnt2=(cnt2+fastpow(p,a[i],mod2))%mod2;
        	}
        	else{
              cnt1=(cnt1-fastpow(p,a[i],mod1)+mod1)%mod1;
              cnt2=(cnt2-fastpow(p,a[i],mod2)+mod2)%mod2;
        	}
        }
        printf("%lld
",cnt1);
    }
	return 0;
}
原文地址:https://www.cnblogs.com/zpj61/p/13435932.html