zoukankan      html  css  js  c++  java
  • 拓展BSGS

    拓展 BSGS

    前置芝士?

    上个 (BSGS) 的没有写是因为可以水博客(大雾

    作用

    (BSGS) 一样,不过是 (gcd(y,p) ot= 1) 的情况

    推导过程

    [y^xequiv z(mod~p) ]

    (d=gcd(y,p))

    将方程改写为等式形式

    [y^x+kp=z ]

    发现此时的 (z) 必须是 (d) 的倍数,否则无解

    因此,除掉 (d)

    [dfrac{y}{d}y^{x-1}+kdfrac pd=dfrac zd ]

    这样前面的 (y/d) 就是一个系数了,

    不断检查 (gcd(frac zd,y)) ,一直除到互质为止

    此时方程就变为

    [dfrac{y^k}{d}y^{x-k}equivdfrac zd(mod~dfrac pd) ]

    然后用 (BSGS) 求解完还原回去就行了

    例题

    SP3105 MOD - Power Modulo Inverted

    思路

    真的是模板,连套路都没有

    代码
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define re register
    
    using namespace std;
    const int HashMod=123456;
    
    inline int read(){
    	re int x=0,f=1;
    	re char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)) {x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return x*f;
    }
     
    int fpow(int a,int b,int mod)
    {
    	int s=1;
    	while(b){
    		if(b&1)
    			s=1ll*s*a%mod;
    			a=1ll*a*a%mod;
    			b>>=1;
    	}
    	return s;
    }
     
    struct HashTable//hash表  
    	{
    		struct Line{ int u,v,next;}e[1000000];
    		int h[HashMod],cnt;
    		void add(int u,int v,int w)
    		{
    			e[++cnt]=(Line){w,v,h[u]};h[u]=cnt;
    		}
    		void Clear(){memset(h,0,sizeof(h));cnt=0;}
    		void Hash(int x,int k){
    			int s=x%HashMod;
    			add(s,k,x);
    		}
    		int query(int x){
    			int s=x%HashMod;
    			for(re int i=h[s];i;i=e[i].next)
    				if(e[i].u==x) return e[i].v;
    				return -1;
    		}
    	}Hash;
    void ex_BSGS(int y,int z,int p){
    	if(y%p==0){
    		puts("No Solution");
    		return ;
    	}
    	y%=p;z%=p;
    	if(z==1) {
    		puts("0");
    		return ;
    	}
    	int k=0,a=1;
    	while(1)
    	{
    		int d=__gcd(y,p);if(d==1)break;
    		if(z%d){puts("No Solution");return;}
    		z/=d;p/=d;++k;a=1ll*a*y/d%p;
    		if(z==a){printf("%d
    ",k);return;}
    	}
    	int m=sqrt(p)+1;Hash.Clear(); 
    	for(re int i=0,t=z;i<m;i++,t=1ll*t*y%p) Hash.Hash(t,i); 
    	for(re int i=1,tt=fpow(y,m,p),t=1ll*a*tt%p;i<=m;i++,t=1ll*t*tt%p)
    	{
    		int b=Hash.query(t);
    		if(b==-1) continue;
    		printf("%d
    ",i*m-b+k);
    		return ;
    	}
    	puts("No Solution");
    }
    
    int main()
    {
    	int x,z,k;
    	while(233)
    	{
    		x=read();z=read();k=read();
    		if(x==0&&z==0&&k==0)break;
    		ex_BSGS(x,k,z);
    	}
    	return 0;
    }
    
  • 相关阅读:
    IfcAxis2Placement3D
    IfcAxis2Placement2D
    IfcAxis1Placement
    realsense 深度数据
    realsense 深度数据
    realsense 深度数据
    sudo fdisk -l
    temviewer历史版本
    100/9801
    IfcPlacement
  • 原文地址:https://www.cnblogs.com/jasony/p/13377350.html
Copyright © 2011-2022 走看看