poj 3696 The Luckiest number

来源:互联网 发布:剑三丐帮成女捏脸数据 编辑:程序博客网 时间:2024/05/16 09:29

题目链接http://poj.org/problem?id=3696

题目描述:求能整除L的全8序列的最短长度

题目分析:设该数字为x   8/9*(10^x-1)=L*p  即 (10^x-1)=9*L*p/8  设m=9*L/gcd(L,8),则存在p1,9*L*p/8=m*p1;方程转化为(10^x-1)=m*p1 即求10^x=1(mod m)的最小解

欧拉公式 10^phi(m)=1(mod m) 求最小解 则答案肯定是phi(m)的因子 然后枚举phi(m)的因子即可    当gcd(10,m)!=1时, 无解

#include<stdio.h>#include<string.h>#include<algorithm>#define ll long longusing namespace std;ll gcd(ll a,ll b){    return b==0?a:gcd(b,a%b);}int i,j,k,x,y,z;ll m,mo;ll mul1(ll a,ll b){    ll n=0;    while (b)    {        if (b&1)            n=(n+a)%mo;        a=a*2%mo;        b=b>>1;    }    return n;}ll mul(ll x){    ll n=1,m=10;    while (x>0)    {        if (x&1)n=mul1(n,m);        m=mul1(m,m);        x=x>>1;    }    return n;}int main(){    int ca=0;    while (scanf("%I64d",&m)&&m)    {        printf("Case %d: ",++ca);        m=m*9/gcd(m,8);        if (gcd(m,10)!=1)        {            printf("0\n");continue;        }        mo=m;        ll rear=m,n=m;        ll p[50][2];int k=0;        for (ll i=2;i*i<=n;i++)        if (n%i==0)        {            rear=rear-rear/i;            do                n/=i;            while(n%i==0);        }        if (n>1)rear=rear-rear/n;//求phi(m)        n=rear;        for (ll i=2;i*i<=n;i++)//对phi(m)进行因式分解        if (n%i==0)        {            p[k][0]=i;            p[k][1]=0;            do            {                n/=i;                p[k][1]++;            }while (n%i==0);            k++;        }        if (n>1)        {            p[k][0]=n;p[k][1]=1;k++;        }        for (i=0;i<k;i++)            for (int j=1;j<=p[i][1];j++)            if (mul(rear/p[i][0])==1)//求最小的x 则满足条件 即除掉。。            rear/=p[i][0];        printf("%I64d\n",rear);    }    return 0;}

原创粉丝点击