• 洛谷 P4861 按钮


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

    首先我们看到题目,每次在(M)进制下对(1)(k),也就是对(k)乘方,最后还是得到(1)

    这样我们就可以列出同余方程(k^xequiv 1 (mod M))

    而初始状态为(1),即(k^0=1)

    所以答案就是满足方程的最小的正整数(x)

    其实这道题是( ext{Ex\_BSGS}),因为题目不满足(k)(M)互质

    考虑我们在做( ext{Ex\_BSGS})时,每次取出(g=gcd(k,M),b'=frac{b}{g},M'=frac{M}{g},k'=frac{k}{g})

    得到新方程(k^{x-1} imes k'equiv b' (mod M'))

    移项得到(k^{x-1}equiv frac{b'}{k'} (mod M'))

    无解的情况就是(g mid b)并且(b e1)

    证明就不证了,不会的可以去看这篇文章QAQ

    直到(g=1),即(k)(M)互质,就可以用(BSGS)求解了

    而题目给的(b)(1),那么我们回去看这个过程,(k,M)不互质说明(g>1)

    [g>1,x e0Rightarrow g mid bRightarrow ext{无解} ]

    所以这个题特判下(k,M)互不互质然后跑(BSGS)就好了

    简单说下(BSGS)怎么写吧

    (n=left lfloor sqrt M ight floor,x=i imes n-j,1le i,jle n),原方程就变为

    [k^{i imes n-j}equiv 1 (mod M) ]

    [(k^n)^iequiv k^j (mod M) ]

    然后把(k^j)求出来哈希一下就可以啦

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <map>
    #include <cmath>
    #define int long long
    using namespace std;
    int m,k;
    map <int,int> f;
    int mypow(int a,int x,int p)   //快速幂
    {
    	int s=1;
    	while (x)
    	{
    		if (x&1)s=s*a%p;
    		a=a*a%p;
    		x>>=1;
    	}
    	return s;
    }
    int gcd(int a,int b)    //最大公约数
    {
    	if (!b)return a;
    	return gcd(b,a%b);
    }
    signed main()
    {
    	cin>>m>>k;
    	if (gcd(m,k)!=1)     //特判无解
    	{
    		cout<<"Let's go Blue Jays!"<<endl;
    		return 0;
    	}
    	int n=ceil(sqrt(m)),b=1;
    	for (int i=1;i<=n;i++)    //k^j
    	{
    		b=b*k%m;
    		f[b]=i;
    	}
    	b=1;
    	int tmp=mypow(k,n,m);
    	for (int i=1;i<=n;i++)    //(k^n)^i
    	{
    		b=b*tmp%m;
    		if (f[b]&&(i*n-f[b]+m)%m!=0)   //有解且不为0
    		{
    			cout<<(i*n-f[b]+m)%m<<endl;
    			return 0;
    		}
    	}
    	cout<<"Let's go Blue Jays!"<<endl;   //无解
    	return 0;
    }
    
  • 相关阅读:
    「初级篇」跟我一起学docker(二)--核心概念和安装
    程序员有哪些借口可以让自己写出低质量的代码?
    「初级篇」跟我一起学docker(一)--认识
    后端程序猿怎么提高技术?提高编码质量?
    河南这么大的省,也所谓的准一线,为什么IT行业就是发展不起来呢?
    JAVA使用Gson解析json数据,实例
    JAVA equals 和 “==”的异同
    JAVA WEB 对返回数据进行按中文名称首字母A~Z升序排序
    JAVA验证数字的正则表达式,来一发
    【转】Java.util.ArrayList.set()方法实例
  • 原文地址:https://www.cnblogs.com/sdlang/p/13068092.html
Copyright © 2020-2023  润新知