HDU 1452 Happy 2004 (唯一分解定理 + 求等比数列前n项和)

来源:互联网 发布:unity3d 沙盒fps源码 编辑:程序博客网 时间:2024/05/16 17:57

题目大意:先求2004^X 的因子和sum , 然后求sum%29.

同POJ 1845 类似。 先将2004分解成素数的乘积。然后对于2004^X , 改写成

    p1^(q1*X) * p2^(q2*X) * ... * pn^(qn*X)

从而知道2004^X的因子的和为

    (1+p1+p1^2+...+p1^(q1*X)) * (1+p2+p2^2+...+p2^(q2*X)) * ... * (1+pn+pn^2+...+pn^(qn*X))

然后用分治法求等比数列的前N项和即可

代码

#include <iostream>using namespace std;typedef long long ll;const int maxn = 100;int p[maxn] , q[maxn] , cnt;void Init(){    int a = 2004;    cnt = 0;    // 唯一分解定理    for(int i = 2; i * i <= a && a != 1; i++) if(a % i == 0) {        p[cnt] = i , q[cnt] = 0;        while(a % i == 0) {q[cnt]++; a /= i;}        cnt++;        if(i != 2) i++;    }    if(a != 1) {p[cnt] = a; q[cnt++]=1;}}// 求a^n % mll pow_mod(ll a , ll n , ll m){    if(n == 0) return 1;    ll x = pow_mod(a , n >> 1 , m);    ll ret = x * x % m;    if(n & 1) ret = ret * a % m;    return ret;}//求(1 + a + a^2 + ... + a^n) % mll sum(ll a , ll n , ll m){    if(!n) return 1;    if(n == 1) return a % m;    ll ret = 0;    if(n&1) {        ret = (1 + pow_mod(a , (n - 1) / 2 + 1 , m)) % m;        ret = (ret * sum(a , (n - 1) / 2 , m)) % m;        ret = (ret + pow_mod(a , (n - 1) / 2 + 1 , m)) % m;    }    else {        ret = (1 + pow_mod(a , n / 2 , m)) % m;        ret = (ret * sum(a , n / 2 , m)) % m;    }    return ret;}int main(){    Init();    int n;    while(cin >> n && n)    {        ll ans = 1 , mod = 29;        for(int i = 0; i < cnt; i++) {           ll tmp = (sum(p[i] , q[i] * n , mod) + 1) % mod;           ans = (ans * tmp) % mod;        }        cout << ans << endl;    }    return 0;}
0 0