HDU 1452 因子和+積性函數+逆元

來源:互聯網
上載者:User

神牛的解釋太精闢了,難以解釋的好...

此題神牛連結http://www.cppblog.com/vontroy/archive/2010/10/02/128356.html

 

計算 2004^X的因子和 s(2004^X) mod M, M=29

s(2004^X)%29
因子和 s是積性函數,即 :gcd(a,b)=1==> s(a*b)= s(a)*s(b)

2004^X=4^X * 3^X *167^X
s(2004^X)= s(2^(2X))* s(3^X) * s(167^X)

如果 p是素數 ==> s(p^X)=1+p+p^2++p^X = (p^(X+1)-1) /(p-1)

s(2004^X)=(2^(2X+1)-1)* (3^(X+1)-1)/2 *(167^(X+1)-1)/166

167%29=22

s(2004^X)=(2^(2X+1)-1)* (3^(X+1)-1)/2 *(22^(X+1)-1)/21

(a*b)/c %M= a%M* b%M * inv(c)

c*inv(c)=1 %M 模為1的所有數 inv(c)為最小可以被c整除的

inv(2)=15, inv(21)=18 2*15=1 mod 29, 18*21=1 mod 29

s(2004^X)=(2^(2X+1)-1)* (3^(X+1)-1)/2 *(22^(X+1)-1)/21
=(2^(2X+1)-1)* (3^(X+1)-1)*15 *(22^(X+1)-1)*18
***************************************************************/

#include<iostream>
#include<cmath>
using namespace std;

int __pow(int a,int n){ ///  求 a^n%29 的解
    int b=1;
    while(n>1){  /// 這段代碼好的難以解釋,二分的思想,自己慢慢體會吧
        if(n%2==0){
            a = a*a%29;
            n /= 2;
        }
        else {
            b = b*a%29;
            n--;
        }
    }
    return a*b%29;
}

int main(){
    int x,a,b,c;
    while(cin>>x,x){  /// 直接求出了逆元
        a = __pow( 2,2*x+1 );
        b = __pow( 3,(x+1) );
        c = __pow( 22,(x+1));
        cout<<(a-1)*(b-1)*15*(c-1)*18%29<<endl;
    }
}

聯繫我們

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