Happy 2004 hdu 1452

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

 

题意:给你一个x,设 n = 2004 ^ x ,求 n的所有因子数之和。

思路:先唯一分解定理,2004可以表示成2 ^ 2 * 3 ^ 1  * 167 ^ 1, 所以n可以分解为2 ^ 2x  * 3 ^ x * 167 ^ x, 然后我们要用到一个知识点, 令s(n)为n的所有因子和,p1, p2, p3,....e1, e2, e3...分别对应唯一分解出的素数和它的知数,  

令g(p, e) = (p^(e+1) - 1) / (p-1),则s(n) = g(p1, e1) * g(p2, e2) * ... * g(pk, ek)。

具体证明可以去看这个大佬的博客https://blog.csdn.net/jc514984625/article/details/72677016

因为这里要对29取模,但我们的g(p, e) 操作涉及到除法,所以我们要求(p - 1)的逆元, 因为mod = 29,是质数,所以根据费马小定理,(p - 1) 的逆元为(p - 1) ^ 27次

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include <map>
using namespace std;
const int MAX = 3000;
typedef long long LL;

int prime[MAX];
int vis[MAX];
int cnt = 0;
LL mod = 29;
LL qpow(LL x, LL n)//计算a^n % mod
{
    LL re = 1;
    while(n)
    {
        if(n & 1)//判断n的最后一位是否为1
            re = (re * x) % mod;
        n >>= 1;//舍去n的最后一位
        x = (x * x) % mod;//将a平方
    }
    return re % mod;
}

int num[] = {2, 1, 1};
int a[] = {2, 3, 167};
int main(){
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	int x;
	while(1){
		scanf("%d", &x);
		if(x == 0){
			break;
		}
		num[2] %= mod;
		LL ans = 1;
		for(int i = 0; i < 3; i++){
			LL t = (qpow(a[i], num[i] * x + 1) - 1); // 快速幂
			LL tt = qpow(a[i] - 1, mod - 2); // 求逆元
			t = t * tt;
			t %= mod;
			ans *= t;
			ans %= mod;
		}

		printf("%I64d\n", ans);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值