• poj3696 The Luckiest number(质数,欧拉函数)


    poj

    题意:给定一个正整数L((L<=2*10^9)),求至少多少个8连在一起组成的正整数是L的倍数?

    分析:x个8连在一起的正整数可写作(8*(10^x-1)/9),于是题目转换为了求一个最小的x,使得(L|8*(10^x-1)/9),整理一下式子得(9*L|8*(10^x-1)),设(d=gcd(9*L,8)).

    所以有(9L/d)与8/d互质,所以式子等价于((9L/d)|10^x-1),所以(10^x≡1(mod(9L/d)))

    若正整数a,n互质,则满足(a^x≡1(mod(m)))的最小正整数(x)(phi(n))的约数.(证明略)

    所以我们可以求出(phi(9L/d)),枚举它的所有约数,用快速幂判断是否满足条件.

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define ll long long
    using namespace std;
    ll gcd(ll a,ll b){
        if(b==0)return a;
        return gcd(b,a%b);
    }
    ll quickmul(ll a,ll b,ll c){
        ll cnt=0;
        while(b){
    		if(b&1)cnt=(cnt+a)%c;
    		a=(a+a)%c;
    		b>>=1;
        }
        return cnt;
    }//快速乘,好像没什么必要
    ll power(ll a,ll b,ll c){
        ll cnt=1;
        while(b){
    		if(b&1)cnt=quickmul(cnt,a,c)%c;
    		a=quickmul(a,a,c)%c;
    		b>>=1;
        }
        return cnt;
    }
    ll get_phi(ll n){
        ll cnt=n;
        for(ll i=2;i*i<=n;++i){
    		if(n%i==0)cnt=cnt/i*(i-1);
    		while(n%i==0)n/=i;
        }
        if(n!=1)cnt=cnt/n*(n-1);
        return cnt;
    }
    int main(){
        ll L,T=0;
        while(scanf("%lld",&L)&&L!=0){	
    		++T;
    		ll n=9*L/gcd(1ll*8,1ll*9*L);ll x=get_phi(n);
    		if(gcd(10,n)!=1){printf("Case %d: 0
    ",T);continue;}
    		int bj=0;
    		for(ll i=1;i*i<=x;i++)
    	    	if(x%i==0&&power(10,i,n)==1){
    				printf("Case %lld: %lld
    ",T,i);
    				bj=1;break;
    	    }
    		if(bj)continue;
    		for(ll i=sqrt(1.0*x);i>=1;i--)
    	    	if(x%i==0&&power(10,x/i,n)==1){
    				printf("Case %lld: %lld
    ",T,x/i);
    				break;
    	    	}
        }
        return 0;
    }
    
    
  • 相关阅读:
    5.16
    4.29
    二十节 作业
    作业
    作业
    控件
    选择排序
    百钱买百鸡
    用颜色变色变换来调整图像的对比度和亮度
    图像的裁剪
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10500388.html
Copyright © 2020-2023  润新知