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

题目地址: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;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值