hdu 1452(因子和+逆元)

Happy 2004

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1393    Accepted Submission(s): 1018


Problem Description
Consider a positive integer X,and let S be the sum of all positive integer divisors of 2004^X. Your job is to determine S modulo 29 (the rest of the division of S by 29).

Take X = 1 for an example. The positive integer divisors of 2004^1 are 1, 2, 3, 4, 6, 12, 167, 334, 501, 668, 1002 and 2004. Therefore S = 4704 and S modulo 29 is equal to 6.
 
Input
The input consists of several test cases. Each test case contains a line with the integer X (1 <= X <= 10000000).

A test case of X = 0 indicates the end of input, and should not be processed.
 
Output
For each test case, in a separate line, please output the result of S modulo 29.
 
Sample Input
1 10000 0
 
Sample Output
6 10
n的因子和为s(n)
令g(p, e) = (p^(e+1) - 1) / (p-1),则s(n) = g(p1, e1) * g(p2, e2) * ... * g(pk, ek)
 
这个题只不过是求nx的因子和而已,假设 n = p1e1p2e2...pnen 那么 nx=p1e1*xp2e2*x...pnen*x  由于这题x的范围比较大,所以要用快速取模,又因为这题有除法取模,而模的数又是一个质数,所以要用到逆元.
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <queue>
using namespace std;
typedef long long LL;
const int N = 10000005;
LL p[3]={2,3,167};
LL e[3]={2,1,1};
LL extend_gcd(LL a,LL b,LL &x,LL &y){
    if( b == 0 ) {
        x = 1;
        y = 0;
        return a;
    }
    else{
        LL x1,y1;
        LL d = extend_gcd(b,a%b,x1,y1);
        x = y1;
        y= x1-a/b*y1;
        return d;
    }
}
LL mod_reverse(LL a,LL n)
{
    LL x,y;
    LL d=extend_gcd(a,n,x,y);
    if(d==1) return (x%n+n)%n;
    else return -1;
}
LL pow_mod(LL a,LL n,LL mod){
    LL ans = 1;
    while(n){
        if(n&1) ans = ans*a%mod;
        a= a*a%mod;
        n=n>>1;
    }
    return ans;
}
LL g(LL p,LL e){
    LL inv = mod_reverse(p-1,29);
    LL ans = (inv*(pow_mod(p,e+1,29)-1))%29;
    return ans;
}
int main()
{
    LL n;
    while(scanf("%lld",&n)!=EOF,n){
        LL m = 2004;
        LL sum = 1;
        for(int i=0;i<3;i++){
            sum = (sum*g(p[i],e[i]*n))%29;
        }
        printf("%lld
",sum);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/liyinggang/p/5521383.html