POJ - 3696 同余

给定\(L\),求最小的\(x\)满足\(L|8(10^x-1)\)

/*H E A D*/
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll euler(ll n){
    ll ans=n;
    for(ll i = 2; i*i <= n; 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 fmp(ll a,ll b,ll m){
    ll ans=0;
    while(b){
        if(b&1) ans=(ans+a)%m;
        a=(a+a)%m;
        b>>=1;
    }
    return ans;
}
ll fpw(ll a,ll n,ll m){
    ll ans=1;
    while(n){
        if(n&1) ans=fmp(ans,a,m);
        a=fmp(a,a,m);
        n>>=1;
    }
    return ans;
}
int main(){
    ll L,kase=0;
    while(cin>>L){
        if(L==0) break;
        L=9ll*L/gcd(L,8);
        printf("Case %lld: ",++kase);
        if(gcd(10,L)!=1){
            println(0);
            continue;
        }
        ll p=euler(L);
        ll ans=p;
        for(ll i=1; i*i<=p; i++){
            if(p%i!=0)continue;
            if(fpw(10,i,L)==1){
                ans=min(ans,i);
            }
            if(i*i!=p&&fpw(10,p/i,L)==1){
                ans=min(ans,p/i);
            }
        }
        println(ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/caturra/p/8448591.html

时间: 2024-08-08 11:17:08

POJ - 3696 同余的相关文章

poj 3696 欧拉函数

poj 3696 题意: 给出一个数字L,求出最短的888...8能被L整除,输出最短的长度. 限制: 1 <= L <= 2*10^9 思路: 设x为最小长度 888...8=(10^x-1)/9*8 由题意得: (10^x-1)/9*8 % L=0 -> (10^x-1)*8 % (9L) = 0 -> (10^x-1) % (9L/gcd(L,8)) = 0 -> 10^x % (9L/gcd(L,8)) = 1 这个是一个离散对数的问题,第一个想到的是用拓展BSGS做

poj 3696 The Luckiest number 欧拉函数在解a^x=1modm的应用

题意: 给一个L,求长度最小的全8数满足该数是L的倍数. 分析: 转化为求方程a^x==1modm.之后就是各种数学论证了. 代码: //poj 3696 //sep9 #include <iostream> #include <algorithm> using namespace std; typedef long long ll; ll L; ll factor[65536]; ll mul(ll x,ll y,ll p) { ll ret=0; while(y){ if(y&

poj 2251(同余)

Ones Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11461   Accepted: 6488 Description Given any integer 0 <= n <= 10000 not divisible by 2 or 5, some multiple of n is a number which in decimal notation is a sequence of 1's. How many d

poj 1426(同余搜索)

Find The Multiple Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26926   Accepted: 11174   Special Judge Description Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal representation contains

POJ 3696

这里面的一个转换的小技巧很重要,把888...8转换成(10^x-1)/9*8.神来之笔,佩服. 这样有(10^x-1)/9*8=L*p得10^x-1=L*p*9/8,设m=9*L/gcd(L,8).这一步如何想到的呢?其实是为了使m与10互质而做的.因为这样必有m*p1=10^x-1.使得同余方程 10^x=1 mod m,相信到了这一步,都知道用欧拉定理了.于是只需求出phi(m),枚举其因子,使得同余方程成立即可 #include <iostream> #include <cstd

POJ 2635 The Embarrassed Cryptographer (同余线性方程+素数筛)

题目地址:POJ 2635 先用素数筛把10^6万以内素数筛出来.然后把输入的那个大数转化成数组,并且每三位存成一个数,这样可以节约内存和时间,然后利用同余线性的原理,对那个小整数以内的所有素数枚举,然后判断是否整除,找到最小的能被整除的. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #i

poj 3349:Snowflake Snow Snowflakes(哈希查找,求和取余法+拉链法)

Snowflake Snow Snowflakes Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 30529   Accepted: 8033 Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Y

POJ 3087 Shuffle&#39;m Up 线性同余,暴力 难度:2

http://poj.org/problem?id=3087 设:s1={A1,A2,A3,...Ac} s2={Ac+1,Ac+2,Ac+3,....A2c} 则 合在一起成为 Ac+1,A1,Ac+2,A2......A2c,Ac 经过一次转换之后变成 s1={Ac+1,A1,Ac+2.....} s2={...A2c,Ac} 对应之前,每个数的序号发生的变化是 +1,+2,+3....-c,-c+1,..... 把整个数链想成环,也相当于是: +1,+2,+3....+c,+c+1,...

POJ 3070 + 51Nod 1242 大斐波那契数取余

POJ 3070 #include "iostream" #include "cstdio" using namespace std; class matrix { public: int a[2][2]; matrix() { a[0][0]=a[1][0]=a[0][1]=1; a[1][1]=0; } }; matrix multi(matrix a,matrix b) { matrix temp; int i,j,k; for(i=0;i<2;i++)