您的位置:首页 > 其它

hdu 4335 What is N?

2013-07-22 17:14 309 查看
此题用到的公式:a^b%c=a^(b%phi(c)+phi(c))%c (b>=phi(c)).

1.当n!<phi(p)时,直接暴力掉;

2.当n!>=phi(p) && n!%phi(p)!=0,用上面公式求;

3.当n!>=phi(p) && n!%phi(p)==0,变为n^(phi(p))%p,找循环节,就可以了

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#define ll unsigned __int64
using namespace std;
ll an[100001];
ll euler(ll n)
{
ll ans=1;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
ans*=i-1;
n/=i;
while(n%i==0)
{
ans*=i;
n/=i;
}
}
}
if(n>1) ans*=n-1;
return ans;
}
ll pows(ll a,ll b, ll mod)
{
ll ans=1;
while(b)
{
if(b&1) ans=(ans*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return ans%mod;
}
int main()
{
int t,k=0;
ll m,ans,fac,c,i,j,phi,b,p;
cin>>t;
while(t--)
{
scanf("%I64u%I64u%I64u",&b,&p,&m);
printf("Case #%d: ",++k);
if(p==1)
{
if(m==18446744073709551615U)
printf("18446744073709551616\n");
else printf("%I64u\n",m+1);
continue;
}
ans=0;fac=1;
phi=euler(p);
//n!<phi(p)
for(i=0;i<=m&&fac<=phi;i++)
{
if(pows(i,fac,p)==b)
ans++;
fac*=(i+1);
}
fac%=phi;
//n!>=phi(p) && n!%phi(p)!=0
for(;i<=m&&fac;i++)
{
if(pows(i,fac+phi,p)==b)
ans++;
fac=(fac*(i+1))%phi;
}
//n!>=phi(p) && n!%phi(p)==0
if(i<=m)
{
ll cnt=0;
//    memset(an,0,sizeof(an));
for(j=0;j<p;j++)
{
an[j]=pows(i+j,phi,p);
if(an[j]==b)
cnt++;
}
c=(m-i+1)/p;
ans+=c*cnt;
ll remind=(m-i+1)%p;
for(j=0;j<remind;j++)
if(an[j]==b)
ans++;
}
printf("%I64u\n",ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: