【poj 3358】Period of an Infinite Binary Expansion(数论同余,欧拉定理)
题意
给定p, q,求
分析
二进制小数是乘二取整
先将
如果出现循环,也就是
因为
令
因为
所以
令
令
求解最小的
欧拉定理的常见应用
(不会的看poj3696的博客)
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll p,q;
ll get_phi(ll n) {
ll res = n;
for(ll i=2;i*i<=n;i++) {
if(n%i==0) {
res = res-res/i;
while(n%i==0){
n/=i;
}
}
}
if(n>1) res = res-res/n;
return res;
}
ll mul(ll a,ll b,ll mod) {
ll res=0;
while(b){
if(b&1) res =(res+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return res;
}
ll qpow(ll a,ll b,ll mod) {
ll res = 1;
while(b) {
if(b&1) res = mul(res,a,mod);
a = mul(a,a,mod);
b>>=1;
}
return res;
}
int main() {
int ca=0;
while(scanf("%lld/%lld",&p,&q)!=EOF){
ll g = __gcd(p,q);
p/=g;q/=g;
ll be = 1;
while(q%2==0) {
q/=2;
be++;
}
ll n = get_phi(q);
ll len = n;
for(ll i=1;i*i<=n;i++) {
if(n%i==0){
if(i < len && qpow(2,i,q)==1) len=i;
if((n/i)<len && qpow(2,n/i,q)==1) len = n/i;
}
}
printf("Case #%d: %lld,%lld\n",++ca,be,len);
}
}