hdu 1452 happy 2004

来源:互联网 发布:社交网络免费观看 编辑:程序博客网 时间:2024/05/30 13:41

设S(x)表示x的因子和。则题目求为:S(2004^X)mod 29
因子和S是积性函数,即满足性质1。

这题还需用到简单的快速幂偷笑偷笑偷笑不然会超时。

性质1 :如果 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)

性质2 :如果 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

性质3 :(a*b)/c %M= a%M * b%M * inv(c)
其中inv(c)即满足 (c*inv(c))%M=1的最小整数,这里M=29
则inv(1)=1,inv(2)=15,inv(22)=15

有上得:
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 <cstdio>#include <cmath>using namespace std;int _pow( int a, int n ){    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;    int 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;    }    return 0;}


 

0 0