HDU 1452 Happy 2004 (积性函数)

题目地址:HDU 1452
性质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 <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
#include <time.h>
using namespace std;
#define LL __int64
#define pi acos(-1.0)
#pragma comment(linker, "/STACK:1024000000")
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const double eqs=1e-9;
const int MAXN=20000+10;
int ksm(int x, int k)
{
        int ans=1;
        while(k){
                if(k&1) ans=ans*x%29;
                k>>=1;
                x=x*x%29;
        }
        return ans;
}
int main()
{
        int x, a, b, c;
        while(scanf("%d",&x)!=EOF&&x){
                a=ksm(2,2*x+1)-1;
                b=(ksm(3,x+1)-1)*15;
                c=(ksm(22,x+1)-1)*18;
                printf("%d\n",a*b*c%29);
        }
        return 0;
}

你可能感兴趣的:(编程,数论,ACM,算法与数据结构)