hdu 3307 简单的指数循环节
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define LL __int64
using namespace std;
LL mult_mod(LL a,LL b,LL c)
{
a%=c;
b%=c;
LL ret=0;
while(b)
{
if(b&1){ret+=a;ret%=c;}
a<<=1;
if(a>=c)a%=c;
b>>=1;
}
return ret;
}
LL PowerMod(LL a, LL b, LL c)
{
LL ans = 1;
LL k = a % c;
while(b>0) //(k*k % c)2^b %c
{
if(b&1)
ans = mult_mod(ans,k,c);
b = b>>1;
k = mult_mod(k,k,c);
}
return ans;
}
LL phi(LL n)
{
LL rea=n,i;
for(i=2;i*i<=n;i++)
{
if(n%i==0)
{
rea=rea-rea/i;
while(n%i==0) n/=i;
}
}
if(n>1)
rea=rea-rea/n;
return rea;
}
/*
from acdreamer http://blog.csdn.net/acdreamers/article/details/8990803
*/
LL gcd(LL X,LL m) //X<m
{
if(X==0){return m;}
return gcd(m%X,X);
}
LL divs[1000005];
LL loop(LL pval,LL X,LL m)
{
int i,size = 0;
for(i=1;i*i<=pval;i++)
{
if(pval%i==0)
{
divs[size++] = i;
divs[size++] = pval/i;
}
}
sort(divs,divs+size);
for(i=0;i<size;i++)
{
if(PowerMod(X,divs[i],m)==1)
{
return divs[i];
}
}
}
int main()
{
LL X,Y,m,c,val,r;
while(scanf("%I64d%I64d%I64d",&X,&Y,&m)!=EOF)
{
c = Y/(X-1);
if(c % m==0){printf("1\n");continue;}
if(c>m)
{
m = m / gcd(m,c);
}
else
{
m = m / gcd(c,m);
}
if(X<m)
{
if(gcd(X,m)!=1){printf("Impossible!\n");continue;}
}
else
{
if(gcd(m,X)!=1){printf("Impossible!\n");continue;}
}
val = phi(m);
r = loop(val,X,m);
printf("%I64d\n",r);
}
}
/*
c * ( X^k -1 ) mod a -> X^k - 1 mod a/gcd(c,m) ;
*/