51Nod1039 N^3 Mod P 数论 原根 BSGS

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

题目传送门 - 51Nod1039

题意

题解

  这题我这个做法要卡常数。

  不好意思我只是来存代码的。

代码

#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)(0.7*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){
    ans.clear();
    for (int k=0;k<a;k++)
        if ((1LL*k*p+c)%a==0)
            ans.push_back((1LL*k*p+c)/a);
}
int main(){
	Get_prime(1e5);
	scanf("%d",&T);
	while (T--){
		scanf("%d%d",&P,&B);
		A=3;
		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;
}

  

原文地址:https://www.cnblogs.com/zhouzhendong/p/51Nod1039.html

时间: 2024-08-02 09:29:25

51Nod1039 N^3 Mod P 数论 原根 BSGS的相关文章

Codeforces 1106F Lunar New Year and a Recursive Sequence (数学、线性代数、线性递推、数论、BSGS、扩展欧几里得算法)

哎呀大水题..我写了一个多小时..好没救啊.. 数论板子X合一? 注意: 本文中变量名称区分大小写. 题意: 给一个\(n\)阶递推序列\(f_k=\prod^{n}_{i=1} f_{k-i}b_i\mod P\)其中\(P=998244353\), 输入\(b_1,b_2,...,b_n\)以及已知\(f_1,f_2,...,f_{n-1}=1\), 再给定一个数\(m\)和第\(m\)项的值\(f_m\), 求出一个合法的\(f_n\)值使得按照这个值递推出来的序列满足第\(m\)项的值为

51nod1039 x^3 mod p

X*X*X mod P = A,其中P为质数.给出P和A,求<=P的所有X. Input 第1行:一个数T,表示后面用作输入测试的数的数量.(1 <= T <= 1000) 第2 - T + 1行:每行两个数P A,中间用空格隔开.(1 <= A < P <= 10^9, P为质数) Output 共T行,每行包括符合条件的X,且0 <= X <= P,如果有多个,按照升序排列,中间用空格隔开.如果没有符合条件的X,输出:No Solution 首先求P的原

【BZOJ 1319】 Sgu261Discrete Rootsv (原根+BSGS+EXGCD)

1319: Sgu261Discrete Roots Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 389  Solved: 172 Description 给出三个整数p,k,a,其中p为质数,求出所有满足x^k=a (mod p),0<=x<=p-1的x. Input 三个整数p,k,a. Output 第一行一个整数,表示符合条件的x的个数. 第二行开始每行一个数,表示符合条件的x,按从小到大的顺序输出. Sample Input 11 3

【CF913G】Power Substring 数论+原根

[CF913G]Power Substring 题意:T组询问,每次给定一个数a,让你求一个k,满足$2^k$的10进制的后$min(100,length(k))$位包含a作为它的子串.你只需要输出一个k,不需要最小化k的值,保证有解. $T\le 2000,a\le 10^{11}$ 题解:神题. 假设a有n位,$2^k=x$,$x=a\times 10^m+b(\mod 10^{n+m})$,我们显然有$k\ge n+m$,所以$2^{n+m}\mid x$,又因为$2^{n+m}\mid

BZOJ 2219 数论之神 BSGS+CRT

题意:链接 方法: BSGS+CRT 解析: 这道题有什么区别呢? 就是他取模的值不是一个质数了 这怎么办呢? 我们来把这个数分解质因数. P=∏piti 然后对于每一个piti我们单独计算. 最后用中国剩余定理合并 这其实跟想象中的中国剩余定理没有什么关系,其实是其中的一个性质,就是mod p的解数总数量等于每一个mod piti的乘积. 这是一个性质,别问我证明. 原方程xA=B(mod C) 转化为xA=B(mod Ci)?>Ci是质数或是质数的幂次. 我们可以单独计算. 这跟之前的题类似

BSGS入门

做了这么长时间数论 应该整合一下 在mod意义下 我们能完成的运算: 加 减(mod m + m mod m) 快速幂 快速乘 逆元(除) 有有解的条件 开方? 这个设计原根的知识 下一篇讲 然后 就是取对数了 也就是著名的 离散对数 问题 (话说连续对数还不太熟练呢.....) Question:  给定方程  a ^ x ≡ b (mod c) 求x Solution: 首先可以容斥地发现 如果有解 0~c范围内一定有一个解 所以枚举! O(c)即可通过本题! End. (啪!) 大部分情况

【51nod】1123 X^A Mod B (任意模数的K次剩余)

题解 K次剩余终极版!orz 写一下,WA一年,bug不花一分钱 在很久以前,我还认为,数论是一个重在思维,代码很短的东西 后来...我学了BSGS,学了EXBSGS,学了模质数的K次剩余--代码一个比一个长-- 直到今天,我写了240行的数论代码,我才发现数论这个东西= =太可怕了 好吧那么我们来说一下任意模数的K次剩余怎么搞 首先,如果模数是奇数,我们可以拆成很多个质数的指数幂,再用解同余方程的方法一个个合起来,细节之后探讨 但是如果,模数有偶数呢 因为要输出所有解,解的个数不多,我们可以倍

各种友(e)善(xin)数论总集(未完待续),从入门到绝望

目录 快速幂 扩展欧几里得 GCD 扩展欧几里得 同余系列 同余方程 同余方程组 一点想法 高次同余方程 BSGS exBSGS 线性筛素数 埃式筛 欧拉筛 欧拉函数 讲解 两道水题 法雷级数 可见点数 原根 欧拉定理 原根部分性质证明(数量证不出来,一个还没填的坑) 扩展:原根的求法 代码 高斯消元 普通 辗转相除法 矩阵树与证明 未了结的坑 无向图 关联矩阵 Kirchhoff矩阵 行列式 求法 代码 证明 柯西-比内公式 小结 @ 快速幂 题目描述 [题意] 求a^b mod c,a,b,

51nod1135(求最小原根)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1135 题意:中文题诶- 思路:设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根.(其中φ(m)表示m的欧拉函数)给出1个质数P,找出P最小的原根. 我们先了解一下阶的概念:满足 a^r Ξ (1 mod m) ---1 的最小 r 即为 a%m的阶,我们可以直接从小到大枚举a, 然后将 r= φ(m) 带入进去, 判断如果满足  1式