求原根模版

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
int p[100000], c;

LL pow_mod(LL a, LL x, LL m)
{
	LL ans = 1;
	while(x)
	{
		if(x&1)
			ans = ans * a % m;
		a = a * a % m;
		x >>= 1;
	}
	return ans;
}

bool ok(int x, int ph, int m)
{
	for(int i = 0; i < c; i++)
		if(pow_mod(x, ph/p[i], m) == 1)
			return false;
	return true;
}
void divide(int x)
{
	c = 0;
	for(int i = 2; i*i <= x; i++)
	{
		if(x % i == 0)
		{
			p[c++] = i;
			while(x % i == 0)
				x /= i;
		}
	}
	if(x > 1)
		p[c++] = x;
}
int main()
{
	int T;
	scanf("%d", &T);
	while(T--)
	{
		int n;
		scanf("%d", &n);
		int m = n, ans = m;
		for(int i = 2; i*i <= n; i++)
		{
			if(n%i == 0)
			{
				ans = ans / i * (i-1);
				while(n%i == 0)
					n /= i;
			}
		}
		if(n > 1)
			ans = ans / n * (n-1);
		//printf("%d\n", ans);
		divide(ans);
		int x = ans;
		while(!ok(x, ans, m))
			x--;
		printf("%d\n", x);
	}
	return 0;
}
时间: 2024-10-24 18:22:32

求原根模版的相关文章

高斯消元 求整数解模版

#include <iostream> #include <string.h> #include <cmath> using namespace std; const int maxn = 105; int equ, var; // 有equ个方程,var个变元.增广阵行数为equ, 分别为0到equ - 1,列数为var + 1,分别为0到var. int a[maxn][maxn]; int x[maxn]; // 解集. bool free_x[maxn]; //

POJ 1284 Primitive Roots (求原根个数)

Primitive Roots 题目链接:http://poj.org/problem?id=1284 利用定理:素数 P 的原根的个数为euler(p - 1) typedef long long ll; using namespace std; /* 求原根 g^d ≡ 1(mod p) 其中d最小为p-1,g 便是一个原根 复杂度:O(m)*log(P-1)(m为p-1的质因子个数) */ ll euler(ll x) { ll res = x; for (ll i = 2; i <= x

POJ1284---Primitive Roots(求原根个数, 欧拉函数)

Description We say that integer x, 0 < x < p, is a primitive root modulo odd prime p if and only if the set { (xi mod p) | 1 <= i <= p-1 } is equal to { 1, -, p-1 }. For example, the consecutive powers of 3 modulo 7 are 3, 2, 6, 4, 5, 1, and t

【数论】【原根】原根的性质以及如何求原根

一个数m如果有原根,则其原根个数为phi(phi(m)).特别地,对素数有phi(p)=p-1. 假设g是奇素数p的一个原根,则g^1,g^2,...,g^(p-1)在模p意义下两两不同,且结果恰好为1~p-1,由此可以定义"离散对数",与连续数学中的对数有异曲同工之妙. 离散对数又叫做"指标",有指标法则:I(ab)≡I(a)+I(b) (mod p-1):I(a^k)≡k*I(a) (mod p-1),由此可以把乘法转化为加法. 指标的求法: #include&

POJ 1284-Primitive Roots(欧拉函数求原根)

Primitive Roots Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1284 Appoint description:  System Crawler  (2015-04-06) Description We say that integer x, 0 < x < p, is a primitive root mod

hdu 4992 Primitive Roots 【求原根模板】

题目链接 大题流程: 判定是否有原根->求出最小原根->利用最小原根找出全部原根 #include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=1e6+5; int prime[maxn+5]; bool check[maxn+5]; int phi[maxn+5]; int num_prime; void init() { memset(check, false, sizeof(

快速求原根的实现

关于原根是什么以及这里的求法 http://www.cnblogs.com/linkzijun/p/6380486.html 在末尾可以看到我之前写的定义和求法以及求法的证明..很巧妙.. 设要求原根的质数为P,这个算法的复杂度大概是O(P-1)*log(P-1),后面是P-1不同质因子的数量 (学习了下tls for的写法..结果结尾忘了写分号..崩了一次,囧 #include <iostream> #include <cstdio> #include <cstring&g

快速求原根

当需要求质数\(P\)的原根\(G\),只需枚举\(a \in [2,P - 1]\),检验对\(P - 1\)的所有质因子\(p_i\),\(a^{\frac{P - 1}{p_I}} \mod P\)是否等于\(0\),若都不等于\(0\),则\(a\)为\(P\)的原根 51Nod原根 #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include&l

求欧拉路径模版 fleury算法

支持多重边,按字典序输出. #include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=510; const int INF=1e9+10; int n,m; int G[maxn][maxn]; int stk[maxn*3],t