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;
}
感受:尼玛,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;
}
相关文章推荐
- poj1845——Sumdiv(数论+幂的因子和)
- 数论poj1845 因子和,等比数列求和
- poj-1845-Sumdiv-数论-快速幂取模+快速分解因式
- poj 1845 Sumdiv (数论)
- POJ 1845(数论 模运算)
- poj 1845(快速幂+二分计算等比数列和+大数因子分解+因子和计算+模除溢出)
- POJ 1845-Sumdiv(数论,A^B的所有约数和)
- [POJ1845]Sumdiv(数论+矩乘)
- [ACM] POJ 1845 Sumdiv(求A的B次方的所有因子的和,一大堆数学公式...,可做模板)
- POJ1845——A的B次方的因子和
- POJ 1845 Sumdiv(数论+快速幂)
- POJ 1845Sumdiv(数论)
- poj-1845 Sumdiv (逆元+费马小定理+因子和)
- poj 1845 所有因子和
- POJ 1845 Sumdiv (数论,约数和)
- poj1845--Sumdiv(数论篇3--真滴是数论啊。。。。)
- poj1845 Sumdiv(数论,因数和,等比数列,快速幂)
- poj 1845 Sumdiv 数论
- poj 1845 数论(唯一分解定理+分治法求等比数列前n项的和mod m的值)
- poj 1845 Sumdiv 数论--等比数列和(逆元或者递归)