您的位置:首页 > 其它

原根

2015-09-15 20:46 337 查看
原根的定义是:

$设d_0是满足a^{d_0}\equiv 1(\%n)的最小的正整数,如果d_0=\varphi (n),那么a是n的原根$

如:

$3$的原根有$2$

$7$的原根有$3,5$

$9$的原根有$2,5$

但是也有可能没有原根,如$10$

但是质数一定有原根,这很重要。

假设$g$是质数$P$的原根,那么有一个很重要的性质:

$g^0,g^1,...,g^{P-2}$和1,2,...,P-1$是一一对应的。

当然,原根不会这么直接考,一般会与FFT,离散对数和N次剩余一起。

好了,就这么多。

原根一般很小,我们直接枚举即可。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj

using namespace std;

typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP;

#define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define fill(a,l,r,v) fill(a+l,a+r+1,v)
#define re(i,a,b)  for(i=(a);i<=(b);i++)
#define red(i,a,b) for(i=(a);i>=(b);i--)
#define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define p_b(a) push_back(a)
#define SF scanf
#define PF printf
#define two(k) (1<<(k))

template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}

const DB EPS=1e-9;
inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
const DB Pi=acos(-1.0);

inline int gint()
{
int res=0;bool neg=0;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return 0;
if(z=='-'){neg=1;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
return (neg)?-res:res;
}
inline LL gll()
{
LL res=0;bool neg=0;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return 0;
if(z=='-'){neg=1;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
return (neg)?-res:res;
}

LL ask_euler(LL n)
{
LL i,tmp=n,res=1;
re(i,2,tmp/i)
if(tmp%i==0)
{
res*=(i-1);
tmp/=i;
while(tmp%i==0)res*=i,tmp/=i;
}
if(tmp!=1)res*=(tmp-1);
return res;
}

LL gcd(LL a,LL b){return (b==0)?a:gcd(b,a%b);}

LL power(LL a,LL k,LL Mod){LL x=1;while(k){if(k&1)x=x*a%Mod;a=a*a%Mod;k>>=1;}return x;}

vector<LL>a;
int g_test(LL g,LL eu,LL n)
{
int i;
if(gcd(g,n)!=1)return 0;
re(i,0,int(a.size())-1)if(power(g,eu/a[i],n)==1)return 0;
return 1;
}

LL primitive_root(LL n)
{
LL i,eu=ask_euler(n),tmp=eu;//如果已知n为质数,那么eu直接等于n-1
a.clear();
re(i,2,tmp/i)
if(tmp%i==0)
{
a.p_b(i);
while(tmp%i==0)tmp/=i;
}
if(tmp!=1)a.p_b(tmp);
LL g=1;
while(!g_test(g,eu,n))g++;
return g;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: