首页 > 其他 > 详细

P4861 按钮

时间:2019-08-11 10:25:23      阅读:85      评论:0      收藏:0      [点我收藏+]

题目背景

Ada被关在了一个房间里。

题目描述

房间的铁门上有一个按钮,还有一个显示屏显示着“1”。 旁边还有一行小字:“这是一个高精度M进制计算器,每按一次按钮,屏幕上的数便会乘以K。当个位数再次变为1时,门就开了。” 由于Ada急于出去,所以你要在1s之内求出她的最小按键次数。

输入格式:

一行,两个整数M和K。

输出格式:

一行一个数字,表示最小按键次数。 如果无论Ada按多少次都无法让门打开,输出"Let‘s go Blue Jays!"(不含引号)。

输入样例

11 2

输出样例

10

输入样例

6 26

输出样例

Let‘s go Blue Jays!

说明

对于30%的数据,2≤M,K≤10^4

对于100%的数据,2≤M,K≤2×10^9

update:

我们不认为个位为11,21,...为问题的解(例如,11在16进制下记为B

思路:

若gcd?(K,M)!=1,则无解。

因为k^x mod M一定是gcd?(K,M)的倍数。

扩展欧几里得&&中国同余定理可知最小的解x一定整除φ(M)

代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

int m,k;
int ans,ans1;
long long x,y;

int ty(int x,int y) {
    int ans=1;
    for (; y; y>>=1,x=(long long)x*x%m)
        if(y&1)
            ans=(long long)ans*x%m;
    return ans;
}

int gcd(int a,int b) {
    if(a<b)
        swap(a,b);
    if(a%b==0)
        return b;
    else
        return gcd(b,a%b);
}

int zc(int n) {
    int ret=n;
    for (int i=2; i*i<=n; i++)
        if (n%i==0) {
            ret=ret/i*(i-1);
            do n/=i;
            while(n%i==0);
        }
    if (n>1)
        ret=ret/n*(n-1);
    return ret;
}

int main () {
    scanf("%d%d",&m,&k);
    if(gcd(m,k)!=1) {
        printf("Let‘s go Blue Jays!\n");
        return 0;
    } else {
        ans=ans1=zc(m);
        for(int i=2; i*i<=ans1; i++)
            if(ans1%i==0) {
                if(ty(k,i)==1)
                    ans=min(ans,i);
                if(ty(k,ans1/i)==1)
                    ans=min(ans,ans1/i);
            }
        printf("%d\n",ans);
    }
    return 0;
}

 

P4861 按钮

原文:https://www.cnblogs.com/mysh/p/11333675.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!