FOJ 1752 && FOJ 1759 (a^b%c 的不同情況)

來源:互聯網
上載者:User

標籤:style   blog   http   os   io   strong   for   ar   

部落格原文地址:http://blog.csdn.net/xuechelingxiao/article/details/38614491


對於一般的求a^b%c的值,當a,b都在long long範圍內,c在1e9的時候,都可以用快速冪模數進行求解。


LL powerMod(LL x, LL k, LL m){    LL res = 1;    while(x %= m, k){        if(k&1) res *= x, res %= m;        x *= x, k >>=1;    }    return res;}



但是當其中的參數變得相對大之後,單純的快速冪可能就不能解決問題了,下面這兩個題就是當a^b%c中某個參數變大之後出現的問題。



FOJ 1752 A^B mod C


題目大意:題意很簡單,就是求a^b%c的結果,只是a,b,c的範圍是 (1<=a,b,c<2^63)。


思路:這個題最關鍵的問題是在快速冪的時候,由於a的最大值是2^63-1,所以會出現乘法溢出,這也是最容易WA的地方。

要解決這個問題,就需要將乘法轉換成加法,進行“快速乘”(暫且這麼叫吧,我也不知道叫啥-。-),就是代碼中的multiplyMod,接下來就沒什麼問題了。


#include <stdio.h>#include <iostream>#define ULL long longusing namespace std;ULL n, m, mod;ULL multiplyMod(ULL x, ULL k, ULL m){    ULL res = 0;    x %= m;    while(k){        if(k&1){            res += x;            if(res >= m)                res -= m;        }        x += x;        if(x >= m){            x -= m;        }        k >>=1;    }    return res;}ULL powerMod(ULL x, ULL k, ULL m){    ULL res = 1;    while(k){        if(k&1){            res = multiplyMod(res, x, m);        }        x = multiplyMod(x, x, m), k >>=1;    }    return res;}int main(){    while(~scanf("%I64d%I64d%I64d", &n, &m, &mod)){        printf("%I64d\n", powerMod(n, m, mod));    }    return 0;}



FOJ 1759 Super A^B mod C


題目大意:一樣的求a^b%c的結果,只是b的範圍變得很大了, (1<=A,C<=1000000000,1<=B<=10^1000000)。


思路:對於這個問題,就需要用到一個公式

A^x = A^(x % Phi(C) + Phi(C)) (mod C)

對於這個公式,可以給出兩個證明的部落格,一個是aekdycoin大犇的證明:http://www.narutoacm.com/archives/a-pow-b-mod-m/

另一個是 http://www.narutoacm.com/archives/a-pow-b-mod-m/


有了理論支援,這個題也就不是什麼問題了,代碼如下。


#include <stdio.h>#include <string.h>#define LL long longint eular(int n){int ret = 1;for(int i = 2; i*i <= n;i++)if(n%i == 0){n /= i, ret *= i-1;while(n%i == 0)n /= i, ret *= i;}if(n > 1)ret *= n-1;return ret;}LL powerMod(LL x, LL k, LL m){    LL res = 1;    while(x %= m, k){        if(k&1) res *= x, res %= m;        x *= x, k >>=1;    }    return res;}LL n, mod;char m[1000005];int main(){    while(~scanf("%I64d%s%I64d", &n, m, &mod)){        LL phi = eular(mod);        int len = strlen(m);        LL num = 0;        for(int i = 0; i < len; ++i){            if(len >= 10){                num = (num*10+(m[i]-'0'))%phi + phi;            }            else {                num = num*10+(m[i]-'0');            }        }        printf("%I64d\n", powerMod(n, num, mod));    }    return 0;}


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.