首页 > 其他 > 详细

FZU 1759 Super A^B mod C(欧拉降幂 )

时间:2020-05-09 19:18:00      阅读:55      评论:0      收藏:0      [点我收藏+]

题目链接

解题思路

??欧拉降幂的模板题,因为C与A不一定互质,所以这里要用到广义欧拉降幂,用广义欧拉降幂的时候记得讨论指数与模数的大小关系。

线性筛选素数

bool u[maxn];
int p[maxn]; char b[maxn];
void pri() {
    for (int i = 2; i<maxn; ++i) {
        if (!u[i]) u[i] = p[++p[0]] = i;
        for (int j = 1; i*p[j]<maxn; ++j) {
            u[i*p[j]] = true;
            if (i%p[j]==0) break;
        }
    }
}

快速幂

ll solve(ll x, ll y, ll m) {
    ll res = x, ans = 1;
    while(y) {
        if (y&1) ans = ans*res%m;
        res = res*res%m;
        y >>= 1;
    }
    return ans;
}

如果指数小于模数的欧拉函数,则直接用快速幂求出答案。

    for (int i = 0; i<len; ++i) numb = numb*10 + b[i]-‘0‘;
    printf("%lld\n", solve(a, numb, c));

否则,求模数的欧拉函数并且进行降幂,然后快速幂求解

ll phi(ll num) {
    ll res = num;
    for (int i = 1; (ll)p[i]*p[i]<=num && i<=p[0]; ++i)
        if (num%p[i]==0) {
            while(num%p[i]==0) num /= p[i];
            res = res/p[i]*(p[i]-1);
        }
    if (num>1) res = res/num*(num-1);
    return res;
}
    ll phic = phi(c);
    for (int i = 0; i<len; ++i) numb = (numb*10 + b[i]-‘0‘)%phic;
    printf("%lld\n", solve(a, numb+phic, c));

完整代码

const int maxn = 1e6+10;
bool u[maxn];
int p[maxn]; char b[maxn];
void pri() {
    for (int i = 2; i<maxn; ++i) {
        if (!u[i]) u[i] = p[++p[0]] = i;
        for (int j = 1; i*p[j]<maxn; ++j) {
            u[i*p[j]] = true;
            if (i%p[j]==0) break;
        }
    }
}
ll phi(ll num) {
    ll res = num;
    for (int i = 1; (ll)p[i]*p[i]<=num && i<=p[0]; ++i)
        if (num%p[i]==0) {
            while(num%p[i]==0) num /= p[i];
            res = res/p[i]*(p[i]-1);
        }
    if (num>1) res = res/num*(num-1);
    return res;
}
ll solve(ll x, ll y, ll m) {
    ll res = x, ans = 1;
    while(y) {
        if (y&1) ans = ans*res%m;
        res = res*res%m;
        y >>= 1;
    }
    return ans;
}
int main(){
    pri(); ll a, c;
    while(~scanf("%lld%s%lld", &a, b, &c)) {
        int len = strlen(b); ll numb = 0;
        if (len>10) {
            ll phic = phi(c);
            for (int i = 0; i<len; ++i) numb = (numb*10 + b[i]-‘0‘)%phic;
            printf("%lld\n", solve(a, numb+phic, c));
        }
        else {
            for (int i = 0; i<len; ++i) numb = numb*10 + b[i]-‘0‘;
            printf("%lld\n", solve(a, numb, c));
        }
    }
    return 0;
}

FZU 1759 Super A^B mod C(欧拉降幂 )

原文:https://www.cnblogs.com/shuitiangong/p/12859474.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!