HDU 1852 快速求冪

來源:互聯網
上載者:User

題目wa了好多回..悲催...不能直接求逆元來計算,還是要用到數論中的小技巧啊...

貼神牛的題解吧..

// 這題主要求S
// 結論: S = (251^(n+1)-1) * (2^(3n+1)-1) / 250
// 是兩個等比數列和相乘
//
// 推理:
// 2008 = 2^3 * 251
// 所以 2008^N 有 3N 個 2 和 N 個251
// 所有僅由2組成的因子有
// 2^0 2^1 2^2 ... 2^(3N)
// 設集合 C = {2^0, 2^1, 2^2 ...,2^(3N)};
// SUM(C) = 2^(3n+1)-1

// 跟251組合產生的因子有
// 251^0 * C
// 251^1 * C
// ...
// 251^N * C

// 所有因子和為:
// S = (251^(n+1)-1))/250 * (2^(3n+1)-1)

// 計算S%K:

// S 很大, 不能儲存在普通的資料類型中, 需要直接計算S%K
// 因為S有個分母250, 設 S = X/250
// 則  S%K = (X/250)%K = (X%(250*K))/250
// 變成先求餘數再除法的形式

知道了數論中的技巧,不能用你逆元來求哇,因為不滿足gcd(250,k )或者gcd(2,k)不一定是互質的, 代碼就不是再是問題了,

 

#include<stdio.h>
int mult(int a1,int n,int k){
    if(n==0) return 1;
    __int64 b=1,a = a1;
    while(n>1){
        if(n%2==0) {
            a=a*a%k;
            n/=2;
        }
        else {
            b=b*a%k;
            n--;
        }
    }
    return a*b%k;
}
int main(){
    int n,k;
    while(scanf("%d%d",&n,&k),n&&k){
        __int64 a=mult(2,3*n+1,250*k);
        __int64 b=mult(251,n+1,250*k);
        a-- , b--;
        a = ( a*b )%(250*k);
        a /= 250;
        printf("%d\n",mult(2008,a,k));
    }
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.