codeforces 17d 欧拉降幂

题意:给你一个b进制,问n位的b进制的数有多少个,把这些数写在纸上,一页纸可以写c个,最后一页写了多少个?

题解:b进制每位只能是 0 ~ b-1,最高为不能为0,所以最高位只有b-1中选择,其他位都有b种选择,所以得出公式:

(b-1)b^{n-1}(mod~c),余数为0,则答案为c。直接算的话显然不行,数据范围太大,于是就请神仙来帮忙:欧拉的降幂公式

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int MAXN = 1e6 + 66;
char b[MAXN], n[MAXN];

ll Eular(ll c){              //欧拉函数值phi()
    ll phi = c;
    for(int i = 2; i * i <= c; i ++){
        if(c % i == 0){
            phi = phi - phi / i;
            while(c % i == 0)
                c = c / i;
        }
    }
    if(c > 1) phi = phi - phi / c;
    return phi;
}

ll quick_pow(ll a, ll x, ll mod){ //快速幂
    ll ans = 1;
    while(x){
        if(x & 1) 
			ans = ans * a % mod;
        a = a * a % mod;
        x = x >> 1;
    }
    return ans % mod;
}
ll cal(char *s, ll mod){    //取模得到b值
    ll res = 0;
    for(int i = 0; i < strlen(s); i ++)
        res = (s[i] - '0' + res * 10) % mod;
    return res;
}
int main(){
    int c;
    scanf("%s %s %d", b, n, &c);
    ll bb = cal(b, c);
    ll phi = Eular(c);
    bool vis = false;    //标记n-1是否大于phi(c)
    ll nn = 0;
    for(int i = 0; i < strlen(n); i ++){ //计算n值
        nn = n[i]-'0'+ nn * 10;
        if(nn >= phi + 1){
            vis = true;
            nn = nn % phi;
        }
    }
    if(vis) nn += phi; //欧拉广义降幂
    ll ans = (quick_pow(bb, nn - 1, c) * (bb - 1) + c)%c;
    if(ans) cout << ans;
    else cout << c;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38759433/article/details/86584652
今日推荐