zoukankan      html  css  js  c++  java
  • 洛谷 P3846 [TJOI2007]可爱的质数

    题意:求一个最小的(L),满足(B^Lequiv N(mod P))

    这就需要用到(BSGS(Baby Step Giant Step))算法了(其实就是个裸的板子题QAQ)

    首先要知道(P)是质数,所以原式中的(L)会在模(P)意义下循环,最小解在([0,P-1])

    我们设(L=i imes m-j),其中(m=left lceil {sqrt P} ight ceil)(1le jle m),

    则方程变为(B^{i imes m-j}equiv N(mod P))

    移项得到((B^{m})^{i}equiv N imes B^{j}(mod P))

    (B,m,n,P)都是已知的,我们选择哈希,把右边(N imes B^{j}mod P)的值预处理出来丢到(map)

    每次枚举(i),计算出((B^{m})^{i}mod P)的值,如果在(map)里出现,说明原方程成立,计算出来的(L)就是最小解了

    有一点要注意的是,如果(B)(P)的倍数,那么(N)必须也是(P)的倍数,否则无解,这个情况特判下就可以了

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <map>
    #include <cmath>
    #define int long long
    using namespace std;
    int p,b,n;
    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;
    }  
    signed main()
    {
    	cin>>p>>b>>n;
    	if (b%p==0&&n%p!=0)
    	{
    		cout<<"no solution"<<endl;
    		return 0;
    	}
    	int m=ceil(sqrt(p)),now=n%p;
    	for (int i=1;i<=m;i++)       //预处理N*B^j mod p
    	{
    		now=now*b%p;
    		if (!f[now])f[now]=i;
    	}                  
    	now=mypow(b,m,p);
    	int tmp=now;             //枚举i
    	for (int i=1;i<=m;i++)
    	{
    		if (f[now])
    		{
    			cout<<((i*m-f[now])%p+p)%p<<endl;  //防止负数
    			return 0;
    		}
    		now=now*tmp%p;
    	}
    	cout<<"no solution"<<endl;
    	return 0;
    }
    
  • 相关阅读:
    Spell checker
    Power Network
    ACM Computer Factory
    Asteroids
    Golang: 并发抓取网页内容
    Golang: 抓取网页内容
    Golang: 读取文件并统计内容
    Golang: 接收命令行输入
    React: 有状态组件生成真实DOM结点
    React: 无状态组件生成真实DOM结点
  • 原文地址:https://www.cnblogs.com/sdlang/p/13068081.html
Copyright © 2011-2022 走看看