Happy 2004(hdu 1452)
题目大意:让你求2004的X次方的所有因子之和除以29的余数。
Sample Input
1
10000
0
Sample Output
6
10
分析:可以知道:2004=4 * 3 *167 , S(2004^X)=S(2^(2X)) * S(3^X) * S(167^X),
由 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) * (167^(X+1)-1)/332;
考虑到 167%29 == 22
原式可写为 S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1) * (22^(X+1)-1)/332
然后求332关于29的乘法逆元,由于29是素数,所以乘法逆元可通过快速幂求得。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int power(int a,int b)///求a的b次方
{
int ans=1;
while(b)
{
if(b&1)
{
ans=ans*a%29;
b--;
}
b>>=1;
a=a*a%29;
}
ans--;
if(ans<0)
return ans+29;
else
return ans;
}
long long quick_mod(long long a,long long b,long long m)
{ ///求乘法逆元的快速幂
long long ans=1;
while(b)
{
if(b&1)
{
ans=ans*a%m;
b--;
}
b>>=1;
a=a*a%m;
}
return ans;
}
int main()
{
int x,a,b;
while(scanf("%d",&x)!=EOF)
{
if(x==0)
return 0;
a=(2*x+1)%28;///2的a次方
b=(x+1)%28;///3,22的b次方
int ans=(int)quick_mod(332,27,29)*power(2,a)*power(3,b)*power(22,b)%29;
cout<<ans<<endl;
}
return 0;
}
Longge's problem(pku 2480)
题目大意:求1~n中每个数与n的最大公约数的和 。
输入:输入数据有多组,每组占一行,输入一个N;
输出:对应于每组输入,输出展一行,输出所求的结果
Sample Input
2
6
Sample Output
3
15
分析:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
long long s,n;
while(scanf("%lld",&n)!=EOF)
{
s=1;
long long x,count;
///x记录每个素数的乘积
///count记录素数的幂
for(long long i=2;i*i<=n;i++)
if(n%i==0)
{
x=1,count=0;
while(n%i==0)
{
n/=i;
x*=i;
count++;
}
s*=(count+1)*x-count*x/i;
}
if(n>1)
s*=(2*n-1);
cout<<s<<endl;
}
return 0;
}

本文解析了两道经典的数学算法题目:“Happy2004”和“Longge's problem”。通过分解质因数的方法简化计算过程,并利用快速幂算法高效地求解大数的幂次运算及乘法逆元。同时介绍了如何使用C++实现这些算法。
323

被折叠的 条评论
为什么被折叠?



