• 51Nod1038 X^A Mod P 数论 原根 BSGS


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

    题目传送门 - 51Nod1038

    题意

    题解

      在模质数意义下,求高次剩余,模板题。

    UPD(2018-09-10): 

      详见数论总结。 

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

     

    代码

    优化了一下代码……原来的那个在这一份后面……

    #include <bits/stdc++.h>
    using namespace std;
    const int N=100005;
    int T,A,B,P;
    int Fac_p[N],Fac_tot,g;
    int prime[N],vis[N],pcnt=0;
    void Get_prime(int n){
    	memset(vis,0,sizeof vis);
    	pcnt=0;
    	for (int i=2;i<=n;i++){
    		if (vis[i])
    			continue;
    		prime[++pcnt]=i;
    		for (int j=i+i;j<=n;j+=i)
    			vis[j]=1;
    	}
    }
    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;
    }
    bool Get_g_Check(int P,int x){
    	for (int i=1;i<=Fac_tot;i++)
    		if (Pow(x,(P-1)/Fac_p[i],P)==1)
    			return 0;
    	return 1;
    }
    int Get_g(int P){
    	Fac_tot=0;
    	int v=P-1;
    	for (int i=1;prime[i]*prime[i]<=v&&i<=pcnt;i++)
    		if (v%prime[i]==0){
    			Fac_p[++Fac_tot]=prime[i];
    			while (v%prime[i]==0)
    				v/=prime[i];
    		}
    	if (v>1)
    		Fac_p[++Fac_tot]=v;
    	for (int i=2;;i++)
    		if (Get_g_Check(P,i))
    			return i;
    	return -1;
    }
    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 BSGS(int A,int B,int P){
    //	Solve x  :   A^x = B (mod p)
    //	ans = aM+b
    	int M=max((int)(sqrt(1.0*P)),1),AM=Pow(A,M,P),AI=Pow(A,P-2,P);
    	Map.clear();
    	for (int b=0,pw=B;b<M;b++,pw=1LL*pw*AI%P)
    		Map.update(pw,b+1);
    	for (int a=0,pw=1;a<P;a+=M,pw=1LL*pw*AM%P){
    		int v=Map.find(pw);
    		if (v)
    			return a+v-1;
    	}
    	return -1;
    }
    int exgcd(int a,int b,int &x,int &y){
    	if (!b){
    		x=1,y=0;
    		return a;
    	}
    	int res=exgcd(b,a%b,y,x);
    	y-=(a/b)*x;
    	return res;
    }
    vector <int> ans;
    void Get_ans(int a,int c,int p){
    	// ax = c (mod p)
    	// ax + py = c
    	int x,y,g=exgcd(a,p,x,y);
    	ans.clear();
    	if (c%g)
    		return;
    	a/=g,c/=g;
    	int P=p/g;
    	x=(1LL*x*c%P+P)%P;
    	while (x<p)
    		ans.push_back(x),x+=P;
    }
    int main(){
        Get_prime(1e5);
    	scanf("%d",&T);
    	while (T--){
    		scanf("%d%d%d",&P,&A,&B);
    		g=Get_g(P);
    		int t=BSGS(g,B,P);
    		Get_ans(A,t,P-1);
    		if (ans.size()<1)
    			puts("No Solution");
    		else {
    			for (vector <int> :: iterator i=ans.begin();i!=ans.end();i++)
    				(*i)=Pow(g,*i,P);
    			sort(ans.begin(),ans.end());
    			for (vector <int> :: iterator i=ans.begin();i!=ans.end();i++)
    				printf("%d ",*i);
    			puts("");
    		}
    	}
    	return 0;
    }
    

      

    #include <bits/stdc++.h>
    using namespace std;
    const int N=105;
    int T,A,B,P;
    int Fac_p[N],Fac_tot,g;
    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;
    }
    bool Get_g_Check(int P,int x){
    	for (int i=1;i<=Fac_tot;i++)
    		if (Pow(x,(P-1)/Fac_p[i],P)==1)
    			return 0;
    	return 1;
    }
    int Get_g(int P){
    	Fac_tot=0;
    	int v=P-1;
    	for (int i=2;i*i<=v;i++)
    		if (v%i==0){
    			Fac_p[++Fac_tot]=i;
    			while (v%i==0)
    				v/=i;
    		}
    	if (v>1)
    		Fac_p[++Fac_tot]=v;
    	for (int i=2;;i++)
    		if (Get_g_Check(P,i))
    			return i;
    	return -1;
    }
    unordered_map <int,int> Map;
    int BSGS(int A,int B,int P){
    //	Solve x  :   A^x = B (mod p)
    //	ans = aM+b
    	int M=(int)sqrt(1.0*P),AM=Pow(A,M,P),AI=Pow(A,P-2,P);
    	Map.clear();
    	for (int b=0,pw=B;b<M;b++,pw=1LL*pw*AI%P)
    		Map[pw]=b+1;
    	int Alim=(P+M-1)/M;
    	for (int a=0,pw=1;a<Alim;a++,pw=1LL*pw*AM%P)
    		if (Map[pw])
    			return a*M+Map[pw]-1;
    	return -1;
    }
    int exgcd(int a,int b,int &x,int &y){
    	if (!b){
    		x=1,y=0;
    		return a;
    	}
    	int res=exgcd(b,a%b,y,x);
    	y-=(a/b)*x;
    	return res;
    }
    vector <int> ans;
    void Get_ans(int a,int c,int p){
    	// ax = c (mod p)
    	// ax + py = c
    	int x,y,g=exgcd(a,p,x,y);
    	ans.clear();
    	if (c%g)
    		return;
    	a/=g,c/=g;
    	int P=p/g;
    	x=(1LL*x*c%P+P)%P;
    	while (x<p)
    		ans.push_back(x),x+=P;
    }
    int main(){
    	scanf("%d",&T);
    	while (T--){
    		scanf("%d%d%d",&P,&A,&B);
    		g=Get_g(P);
    		int t=BSGS(g,B,P);
    		Get_ans(A,t,P-1);
    		if (ans.size()<1)
    			puts("No Solution");
    		else {
    			for (vector <int> :: iterator i=ans.begin();i!=ans.end();i++)
    				(*i)=Pow(g,*i,P);
    			sort(ans.begin(),ans.end());
    			for (vector <int> :: iterator i=ans.begin();i!=ans.end();i++)
    				printf("%d ",*i);
    			puts("");
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Mysql学习总结(19)——Mysql无法创建外键的原因
    Java Web学习总结(21)——http协议响应状态码大全以及常用状态码
    Java Web学习总结(21)——http协议响应状态码大全以及常用状态码
    Tomcat学习总结(5)——Tomcat容器管理安全的几种验证方式
    Android学习总结(1)——好的 Android 开发习惯
    phabricator
    linux-kernel 学习计划
    【华为云技术分享】Linux内核编程环境 (1)
    7 分钟全面了解位运算
    【华为云技术分享】鲲鹏弹性云服务器GCC交叉编译环境搭建指南
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/51Nod1038.html
Copyright © 2020-2023  润新知