zoukankan      html  css  js  c++  java
  • FZU 1759 Super A^B mod C(欧拉降幂 )

    题目链接

    解题思路

      欧拉降幂的模板题,因为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
    ", 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
    ", 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
    ", solve(a, numb+phic, c));
            }
            else {
                for (int i = 0; i<len; ++i) numb = numb*10 + b[i]-'0';
                printf("%lld
    ", solve(a, numb, c));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    USACO 之 Section 2.2 (已解决)
    USACO 之 Section 2.1 (已解决)
    《C++ Primer》学习 之 函数指针相关用法
    《C++ Primer》学习 之 const_cast使用
    《C++ Primer》学习 之 返回数组的引用(返回数组的指针,方法与之相同)
    USACO 之 Section 1.5 (已解决)
    USACO 之 Section 1.4 More Search Techniques (已解决)
    [NN] 对于BackPropagation(BP, 误差反向传播)的一些理解
    [CLPR] 定位算法探幽
    [LeetCode系列] 双单链表共同节点搜索问题
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12859474.html
Copyright © 2011-2022 走看看