zoukankan      html  css  js  c++  java
  • BZOJ2480 Spoj3105 Mod 数论 扩展BSGS

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2480.html

    题目传送门 - BZOJ2480

    题意

      已知数 $a,p,b$ ,求满足 $a^x≡b pmod p $ 的最小自然数 $x$ 。

      $a,p,bleq 10^9$ 

    题解

      ExBSGS模板题。

    UPD(2018-09-10): 

      详见数论总结。 

      传送门 - https://www.cnblogs.com/zhouzhendong/p/Number-theory-Residue-System.html

     

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int a,p,b;
    int Pow(int x,int y,int mod){
    	int ans=1;
    	for (;y;y>>=1,x=1LL*x*x%mod)
    		if (y&1)
    			ans=1LL*ans*x%mod;
    	return ans;
    }
    int gcd(int x,int y){
    	return y?gcd(y,x%y):x;
    }
    struct hash_map{
    	static const int Ti=233,mod=1<<16;
    	int cnt,k[mod+1],v[mod+1],nxt[mod+1],fst[mod+1];
    	int Hash(int x){
    		int v=x&(mod-1);
    		return v==0?mod:v;	
    	}
    	void clear(){
    		cnt=0;
    		memset(fst,0,sizeof fst);
    	}
    	void update(int x,int a){
    		int y=Hash(x);
    		for (int p=fst[y];p;p=nxt[p])
    			if (k[p]==x){
    				v[p]=a;
    				return;
    			}
    		k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt,v[cnt]=a;
    		return;
    	}
    	int find(int x){
    		int y=Hash(x);
    		for (int p=fst[y];p;p=nxt[p])
    			if (k[p]==x)
    				return v[p];
    		return 0;
    	}
    	int &operator [] (int x){
    		int y=Hash(x);
    		for (int p=fst[y];p;p=nxt[p])
    			if (k[p]==x)
    				return v[p];
    		k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt;
    		return v[cnt]=0;
    	}
    }Map;
    int ExBSGS(int A,int B,int P){
    	A%=P,B%=P;
    	int k=0,v=1;
    	while (1){
    		int g=gcd(A,P);
    		if (g==1)
    			break;
    		if (B%g)
    			return -1;
    		k++,B/=g,P/=g,v=1LL*v*(A/g)%P;
    		if (v==B)
    			return k;
    	}
    	if (P==1)
    		return k;
    	int M=max((int)sqrt(1.0*P),1),AM=Pow(A,M,P);
    	Map.clear();
    	for (int b=0,pw=B;b<M;b+=1,pw=1LL*pw*A%P)
    		Map.update(pw,b+1);
    	for (int a=M,pw=1LL*v*AM%P;a-M<P;a+=M,pw=1LL*pw*AM%P){
    		int v=Map.find(pw);
    		if (v)
    			return a-(v-1)+k;
    	}
    	return -1;
    }
    int main(){
    	while (~scanf("%d%d%d",&a,&p,&b)&&(a||b||p)){
    		int ans=ExBSGS(a,b,p);
    		if (~ans)
    			printf("%d
    ",ans);
    		else
    			puts("No Solution");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    linux的别名(alias/unalias)
    asp.net <%%> <%#%><%=%><%@%><%$%>用法与区别
    SQL获取刚插入的记录的自动增长列ID的值
    包和继承
    面对对象编程(封装)
    面对对象编程(上)
    数组(下)
    java数组-如何在一堆数据中使用数组!
    Request和Response学习笔记5
    Request和Response学习笔记4
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ2480.html
Copyright © 2011-2022 走看看