您的位置:首页 > 其它

poj——1845(数论之因子的和)

2013-08-12 13:38 239 查看
题目地址:http://poj.org/problem?id=1845

感受:尼玛,0的正整数次方mod9901的结果竟然是1,严重毁三观加坑啊。

解析:就是用等比数列公式加上逆元做的。注如果(p-1)是9901的倍数的话,就直接乘以(count*k+1)个1便可以。(可证明的)。

#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
#define INF 0xfffffff
#define MAX(a,b) a>b?a:b
#define MIN(a,b) a>b?b:a
ll pow_mod(ll x,ll y,ll MOD) //快速幂mod(递归实现) 求逆元。
{
if(y==1) return x;
ll ans=pow_mod(x,y/2,MOD);
return y%2?((ans*ans)%MOD*x)%MOD:(ans*ans)%MOD;
}
int main()
{
ll i,j,k,t;
ll m,n;
ll ans;
ll MOD=9901;
ll temp;
while(scanf("%I64d %I64d",&n,&k)!=-1)
{
if(k==0||n==0) cout<<"1"<<endl; //此处坑啊。
else
{
ans=1;
int Count=0;
if(n%2==0)
{
while(n%2==0)
{
n/=2;
Count++;
}
ll y=(Count*k+1)%(MOD-1);
ans=(ans*((pow_mod(2,y,MOD)+MOD-1)%MOD))%MOD;
}
for(i=3;i*i<n&&n!=1;i+=2)
{
if(n%i==0)
{
Count=0;
while(n%i==0)
{
n/=i;
Count++;
}
if((i-1)%MOD==0) //如果p-1是MOD倍数的特殊情况,此时没有逆元
{
ans=ans*(Count*k+1)%MOD;
}
else
{
temp=pow_mod(i-1,MOD-2,MOD); //temp就是求的逆元
ll y=(Count*k+1)%(MOD-1); //由于MOD的数是素数,利用了费马小定理
ans=(ans*(((temp*pow_mod(i,y,MOD))%MOD-temp+MOD)%MOD))%MOD;
}
}
}
if(n!=1)
{
if((n-1)%MOD!=0)
{
temp=pow_mod(n-1,MOD-2,MOD);
ans=(ans*((temp*pow_mod(n,k+1,MOD)%MOD-temp+MOD)%MOD))%MOD;
}
else
{
ans=ans*(k+1)%MOD;
}
}
printf("%I64d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: