1. 程式人生 > >ACM數論之原根

ACM數論之原根

用途1:

  • 可以將模p系統下的一些數轉化為原根表示,即g^{i},將每個數出現的次數作為係數。這樣就可以表示一個多項式f(g)=a_{0}+a_{1}g^{1}+...+a_{n}g^{n},可以配合FFT。

【一個素數的原根求法】

素數p的尤拉函式值為p-1

#include<bits/stdc++.h>
using namespace std;

ll qpow(ll n,ll m,ll p)
{
    ll ans=1;
    n%=p;
    for(;m;m>>=1,n=n*n%p)
        if(m&1)ans=ans*n%p;
    return ans;
}
int pri[MAX],tot;
ll getRoot(ll p) //求質數p的最小原根
{
    tot=0;
    ll n=p-1,sq=sqrt(p+0.5);
    for(int i=2;i<=sq;i++)if(n%i==0)
    {
        pri[tot++]=i;
        while(n%i==0)n/=i;
    }
    if(n>1)pri[tot++]=n;
    for(int g=2;g<=p-1;g++) //試探每一個g是否原根
    {
        int flag=1;
        for(int i=0;i<tot;i++)if(qpow(g,(p-1)/pri[i],p)==1)
        {
            flag=0; break;
        }
        if(flag)return g;
    }
    return -1; //沒有原根
}


int main()
{
    int p;
    cin>>p;
    cout<<"原根="<<getRoot(p)<<endl;
}