CF359C Prime Number
我这个题解可能好理解一些。o( ̄▽ ̄)o
Solution
我开始的思路:因为 \(x\) 为质数,那 \(\gcd\) 肯定是 \(x^k\) 啊!不就是找一下 \(a_i\) 的最小值,用 \(sum\) 一减最后来个快速幂吗,然后样例 \(1\) 就干没我了。≧ ﹏ ≦
然后发现在提取了最小的因子之后,一些指数变为 \(0\) 的数字之和可能是 \(x\) 的倍数,所以在我们不断找最小因子的时候需要求+判断指数变为 \(0\) 的数字。
细节:因为 \(a_i\leq 10^9\) ,如果加起来的可以稍微用扩展欧拉定理将指数取个小模(其实不用,因为我没用就过了没大多少)
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+5,mod=1e9+7;
ll a[N],n,x,cnt,sum,num[N];
inline ll fpow(ll a,ll b){
ll res=1;
while(b){
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
ll calc(ll x,ll y){
ll res=0;
while(x&&(x%y==0)){
res++;
x/=y;
}
return res;
}
int main(){
scanf("%lld%lld",&n,&x);
for(int i=0;i<n;i++){
scanf("%lld",&a[i]);
sum+=a[i];
}
for(int i=0;i<n;i++)
num[i]=sum-a[i];
sort(num,num+n);
ll tot=1,now=num[0],tmp;
int pos=0;
while(233){
while(pos+1<n&&num[pos+1]-cnt==now) tot++,pos++;
cnt+=now;
if((tot%x)||(now==0)){
tmp=min(sum,cnt);
ll ans=fpow(x,tmp);
printf("%lld\n",ans);
break;
}
now=calc(tot,x);
if(pos+1<n) now=min(now,num[pos+1]-cnt);//从新定位当前最小的因子
for(int i=1;i<=now;i++) tot/=x;
}
return 0;
}