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;
}
posted @ 2020-09-26 09:13  jasony_sam  阅读(126)  评论(0编辑  收藏  举报