​传送门​

题目大意

给你一个质数和一个序列Codeforces 359 C_5e
计算Codeforces 359 C_5e_02。对和式通分后得到Codeforces 359 C_5e_03,其中,Codeforces 359 C_5e_04,现在,要求你求出Codeforces 359 C_5e_05Codeforces 359 C_i++_06的最大公因子,答案对Codeforces 359 C_5e_07取余。

思路

我们知道Codeforces 359 C_i++_08
Codeforces 359 C_5e_09
若是存在Codeforces 359 C_5e_10Codeforces 359 C_5e_11,那么可以合并成一个Codeforces 359 C_i++_12,我们可以一直合并,去最小的Codeforces 359 C_5e_13就是答案。

代码

const int maxn = 1e6+7;
const ll mod = 1e9+7;
const ll INF=5e18+7;
const int inf=1e9+7;
const ll maxx=1e6+700;

ll qpow(ll a,ll b,ll p)
{
ll ans=1;
a=a%p;
while(b)
{
if(b&1)
ans=1ll*ans*a%p;
a=1ll*a*a%p;
b>>=1;
}
return ans%p;
}

ll n,x;
ll num[maxn];
ll f[maxn];
map<ll,ll>mp;map<ll,ll>::iterator it;
int main(){
scanf("%lld%lld",&n,&x);
ll sum=0,sum2=0;
for(int i=1;i<=n;i++){
scanf("%lld",&num[i]);
sum+=num[i];
}
for(int i=1;i<=n;i++){
mp[sum-num[i]]++;
}
ll min1=sum;
for(it=mp.begin();it!=mp.end();it++){
if(it->second/x) mp[it->first+1]+=it->second/x;
it->second-=it->second/x*x;
if(it->second) min1=min(min1,it->first);
}
//cout<<min1<<endl;
printf("%lld\n",qpow(x,min1,mod));
}