您的位置:首页 > 移动开发

hdu 1452 Happy 2004 因子和

2013-10-17 17:45 330 查看
题意:输入x,求2004^x的所有因子的和,结果对29取余。

题解:肯定不能暴力的,需要想别的方法,我们知道的是:一个数X=p1^t1*p2^t2*...*pk^tk(其中pi为质数)。则因子个数为(t1+1)*(t2+1)*...*(tk+1)。怎么得出的?枚举每个指数0~ti,我们就可以得到所有的因子。所以因子和sum=p1^0*p2^0*...*pk^0+p1^0*p2^0*...*pk^1+......+p1^t1*p2^t2*..pk^tk=(p1^0+p1^1...+pk^t1)*...*(pk^0+pk^1+...+pk^tk)。这样就是求等比数列的和的乘积了。接下来就简单了,2004=2^2*3*167,所以2004^x=2^2x*3^x*167^x,因子和sum=(2^0+...+2^2x)*(3^0+...3^x)*(167^0+...+167^x)=(2^(2x+1)-1)*((3^(x+1)-1)/2)*((167^(x+1)-1)/166)。逐个取余既可。

这里的除法取余以前讲过,两种方法:

1.(a/b)%mod=a%(b*mod)/b%mod;

2.(a/b)%mod=a*b^(mod-2)%mod,mod为素数(可以通过逆元证明)

耗时:0MS/1000MS

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int mod=29;
int pow_mod(int a,int b)
{
	int s=1;
	while(b)
	{
		if(b&1)s=(s*a)%mod;
		a=(a*a)%mod;
		b=b>>1;
	}
	return s;
}
int find(int a,int b)
{
	int i,j,k,p,ans;
	ans=pow_mod(a,b+1)-1;
	ans=(ans+mod)%mod;
	ans=ans*pow_mod(a-1,mod-2)%mod;
	return ans;
}
int main()
{
	int x;
	while(cin>>x)
	{
		if(x==0)break;
		cout<<find(2,2*x)*find(3,x)*find(167,x)%mod<<endl;
	}
	return 0;
}
/*
2004=2*2*3*167;
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: