【POJ3358】Period of an Infinite Binary Expansion-欧拉定理+数论好题
测试地址:Period of an Infinite Binary Expansion
题目大意:对于一个小于1的有理数
做法:可恶啊!明明方程都推出来了,可就是做不出来,好气啊,没办法只能看了题解……
首先我们可以将
将式子转换一下变成:
以下是本人代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
ll p,q,fac[30];
ll gcd(ll a,ll b)
{
return (b==0)?a:gcd(b,a%b);
}
ll mult(ll a,ll b,ll mod)
{
a%=mod,b%=mod;
ll s=a,sum=0;
while(b)
{
if (b&1)
{
sum+=s;
if (sum>=mod) sum-=mod;
}
b>>=1;s<<=1;
if (s>=mod) s-=mod;
}
return sum;
}
ll power(ll a,ll b,ll mod)
{
ll s=a,sum=1;
while(b)
{
if (b&1) sum=mult(sum,s,mod);
b>>=1;s=mult(s,s,mod);
}
return sum;
}
ll phi(ll x)
{
ll p=x;
for(int i=2;i*i<=x;i++)
if (!(x%i))
{
p=p/i*(i-1);
while(!(x%i)) x/=i;
}
if (x>1) p=p/x*(x-1);
return p;
}
void find_factor(ll x)
{
fac[0]=0;
for(int i=2;i*i<=x;i++)
if (!(x%i))
{
fac[++fac[0]]=i;
while(!(x%i)) x/=i;
}
if (x>1) fac[++fac[0]]=x;
}
int main()
{
int t=0;
while(scanf("%lld/%lld",&p,&q)!=EOF)
{
t++;
ll d=gcd(p,q),i=0,j;
p/=d,q/=d;
while(!(q%2)) {q>>=1;i++;}
i++;
j=phi(q);
find_factor(j);
for(int i=1;i<=fac[0];i++)
{
while(1)
{
j/=fac[i];
if (power(2,j,q)!=1)
{
j*=fac[i];
break;
}
else if (j%fac[i]) break;
}
}
printf("Case #%d: %lld,%lld\n",t,i,j);
}
return 0;
}