原根

原根

定义:如果 g(modm) 的阶为 ϕ(m)gm 的原根

g0,g1,...gϕ(m)1 构成了模 m 的简化剩余系 (即 [1,m1] 中与 m 互质的数可以被原根 g 的阶表示出来)

只有 1,2,4,pa,2pa(p,a) 存在原根

对于素数 p, 有如下性质

  1. p 的原根有 ϕ(p1)

  2. p 的原根大致随机分布在 2 ~ p - 1 中

  3. 由 1,2 两条性质,p 的最小的原根不会很大,因此求最小原根只需从 2 开始枚举,判断是否是原根即可

  4. p 的原根不一定是 p2 的原根,p2 的原根一定是更高次的原根

原根 - 题目 - Daimayuan Online Judge

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;
typedef long long ll;
int divisor[100];

ll qmi(ll a, ll b, ll p)
{
	ll ans = 1;
	while(b)
	{
		if (b & 1) ans = ans * a % p;
		b >>= 1;
		a = a * a % p;
	}
	return ans % p;
}
int solve(int p)
{
	int t = 0;
	int now = p - 1;
	for (int i = 2; i <= now / i; i++)
	{
		if (now % i) continue;
		divisor[++t] = i;
		while(now % i == 0) now /= i;
	}
	if (now > 1) divisor[++t] = now;
	
	for (int g = 1; g < p; g++)
	{
		bool flag = true;
		for (int i = 1; i <= t; i++)
		{
			int d = divisor[i];
			if (qmi(g, (p - 1) / d, p) == 1) //如果 phi(p-1) 能除以一个因子,那这个 g 就不是原根
			{
				flag = false;
				break;
			}
		}
		if (flag) return g;
	}
}
int main()
{
	int T;
	scanf("%d\n", &T);
	while(T--)
	{
		int p;
		scanf("%d", &p);
		printf("%d\n", solve(p));
	}
	return 0;
}
posted @   hzy0227  阅读(96)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示