题目:求 q/p 二进制小数的循环节,起点和长度。
若满足 2^phi[ n ] = 1 (mod n ) 则 数 t = phi [ n ] 一定有一个使 2^k=1 (mod n )成立的 因子 k
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#define bug(a) cout<<a<<"--->\n";
#define N 100000
using namespace std;
typedef unsigned long long LL;
LL euler_phi(LL n)
{
LL m=(LL)sqrt(n+0.5);
LL ans=n;
for(LL i=2;i<=m;i++)
{
if(n%i==0){
ans=ans/i*(i-1);
while(n%i==0) n/=i;
}
}
if(n>1) ans=ans/n*(n-1);
return ans;
}
LL gcd(LL a,LL b)
{
LL r;
if(b>a) swap(a,b);
while(b)
{
r=a%b;
a=b;
b=r;
}
return a;
}
void factor(LL n,LL *fac,int &cnt) //求因数,保存于 fac[1001]
{
cnt=0;
LL m=(LL)sqrt(n+0.5);
for(LL i=1;i<=m;i++)
{
if(n%i==0)
{
fac[cnt++]=i;
fac[cnt++]=n/i;
}
}
sort(fac,fac+cnt);
}
LL qpow(LL a,LL b,LL p)
{
LL ans=1;
while(b)
{
if(b&1) ans=ans*a%p;
a=a*a%p;
b>>=1;
}
return ans;
}
int main()
{
LL p_,q_;
LL p,q;
char c;
int t=0;
while(scanf("%I64d%c%I64d",&p_,&c,&q_)!=EOF)
{
LL g=gcd(p_,q_);
p=p_/g;
q=q_/g;
int m=0;
while(q%2==0)
{
q/=2;
m++;
}
int cnt;
LL fac[1001];
factor(euler_phi(q),fac,cnt);
int i;
for(i=0;i<cnt;i++)
{
if(qpow(2,fac[i],q)==1)
break;
}
printf("Case #%d: %d,%I64d\n",++t,m+1,fac[i]);
}
return 0;
}