程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 1852 快速求冪

HDU 1852 快速求冪

編輯:C++入門知識

題目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));
    }
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved