首页 > 代码库 > POJ 3358 (欧拉定理)
POJ 3358 (欧拉定理)
题目:求 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; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。