HDU 2462 The Luckiest number

题意:给一个数L,是否存在一个数乘上L后的结果只有8,求最小的结果的位数
思路:
自己感觉没有想法就看了下别人的思路,ORZ
令 M=NL
M=(10^X-1)/9*8
M=0 (mod L)
(10^x-1)/9*8=0(mod L)->(10^x-1)=0(mod 9L/Gcd(L,8))
->10^x=1(mod 9L/Gcd(L,8))
这时候就可以用欧拉定理啦
mod=9L/Gcd(L,8)
10^phi(mod)=1 (mod mod)
但是题目求得是最小解,所以枚举phi(mod)的所有因子
这里要注意快速幂的时候由于mod是LL的,所以会爆LL
快速幂内乘法也要用二进制的思想来a*a%mod

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x&(-x))
typedef long long LL;
#define maxn 10005
const int inf=(1<<28)-1;
LL get_phi(LL n)
{
    LL res=n,m=n;
    for(LL i=2;i*i<=m;++i)
    if(m%i==0)
    {
        res=res/i*(i-1);
        while(m%i==0) m/=i;
    }
    if(m>1) res=res/m*(m-1);
    return res;
}
LL Gcd(LL a,LL b)
{
    if(!a) return b;
    return Gcd(b%a,a);
}
LL modular_multi(LL a, LL b, LL c) {// a * b % c
    LL res, temp;
    res = 0, temp = a % c;
    while (b) {
        if (b & 1) {
            res += temp;
            if (res >= c) {
                res -= c;
            }
        }
        temp <<= 1;
        if (temp >= c) {
            temp -= c;
        }
        b >>= 1;
    }
    return res;
}
LL modular_exp(LL a, LL b, LL c) { //a ^ b % c 改成mod_pow就不行,中间发生了溢出,还是这个模板靠谱
    LL res, temp;
    res = 1 % c, temp = a % c;
    while (b) {
        if (b & 1) {
            res = modular_multi(res, temp, c);
        }
        temp = modular_multi(temp, temp, c);
        b >>= 1;
    }
    return res;
}
LL factor[2000005];
int main()
{
    LL l,Case=0;
    while(~scanf("%lld",&l)&&l)
    {
        printf("Case %lld: ",++Case);
        LL m=l/Gcd(l,8)*(LL)9;
        if(Gcd(10,m)!=1)
        {
            printf("0\n");
            continue;
        }
        LL ph=get_phi(m),len=0;
        for(LL i=1;i*i<=ph;++i)
        if(ph%i==0)
        {
            factor[++len]=i;
            if(i*i!=ph) factor[++len]=ph/i;
        }
        sort(factor+1,factor+len+1);
        int flag=1;
        for(LL i=1;i<=len;++i)
        if(modular_exp(10,factor[i],m)==1)
        {
            printf("%lld\n",factor[i]);
            flag=0;
            break;
        }
        if(flag)
        printf("%lld\n",ph);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值