CF359C Prime Number

我这个题解可能好理解一些。o( ̄▽ ̄)o

Solution

我开始的思路:因为 (x) 为质数,那 (gcd) 肯定是 (x^k) 啊!不就是找一下 (a_i) 的最小值,用 (sum) 一减最后来个快速幂吗,然后样例 (1) 就干没我了。≧ ﹏ ≦

​ 然后发现在提取了最小的因子之后,一些指数变为 (0) 的数字之和可能是 (x) 的倍数,所以在我们不断找最小因子的时候需要求+判断指数变为 (0) 的数字。

细节:因为 (a_ileq 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
",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;
}
原文地址:https://www.cnblogs.com/jasony/p/13733780.html