POJ 3358 (欧拉定理)

来源:互联网 发布:php获取post json数据 编辑:程序博客网 时间:2024/06/06 11:43

题目:求 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 100000using 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;}




0 0
原创粉丝点击