题目:求 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; }
POJ 3358 (欧拉定理)
时间: 2024-10-09 05:49:15