hdu 4335 欧拉函数的应用(降幂) 快速幂

注意当b=0 p=1 m=2^64-1 时结果为m+1需要特殊处理

降幂公式:

A ^{x}(mod m)=A^(x%\phi (m)+\phi (m)) (mod m);

还有就是可能long long 过不了,要用 unsigned long long

代码:

#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string> 
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional> 
#define PI acos(-1)
#define ll unsigned long long
using namespace std;
const int INF = 0x3f3f3f3f;
const ll N=1e6+10;
ll Pow(ll base,ll n,ll mod)
{
    ll result=1;
    base=base%mod;
    while(n>0)
    {
       if(n&1)result=result*base%mod;
       base=base*base%mod;
       n=n>>1;
	}
	return result;
}
ll Phi(ll n)
{
  ll t=n;
  for(ll i=2;i*i<=n;i++)
  {
     if(n%i==0)
     {
        t=t-t/i;
        while(n%i==0)n=n/i;
	 }
  }
  if(n!=1)t=t-t/n;
  return t;
}
void solve(ll b,ll mod,ll n)
{
    ll phi=Phi(mod),result=1,x=0;
    if(b==0)x++;
	for(ll i=1;i<phi&&i<=n;i++)
    {
       result=result*i%phi+phi;
	   if(Pow(i,result,mod)==b)x++;
	}
	for(ll i=phi;i<=n&&i<phi+mod;i++)
	{
	   if(Pow(i,phi,mod)==b)
	   {
	      x=x+(n-i)/mod+1;
	   }
	}
	cout<<x<<endl;
}
int main()
{
  int t;
  ll b,mod,n;
  ll cas=1;
  cin>>t;
  while(t--)
  {
     cin>>b>>mod>>n;
     if(b==0&&mod==1&&n==18446744073709551615)
     {
        printf("Case #%d: 18446744073709551616\n",cas++);
        continue;
	 }
	 printf("Case #%d: ",cas++);
     solve(b,mod,n);
  }
} 

猜你喜欢

转载自blog.csdn.net/jun_____/article/details/82185162