使用NTT需要保证模数mod 为质数。
通过以下代码求得一个模数的原根 , 常见的质数的原根 998244353 -> 3 1e9+7 -> 5
#include<bits/stdc++.h>
#define ll long long
#define IL inline
#define RG register
using namespace std;
ll prm[1000],tot,N,root;
ll Power(ll bs,ll js,ll MOD){
ll S = 1,T = bs;
while(js){
if(js&1)S = S*T%MOD;
T = T*T%MOD;
js >>= 1;
} return S;
}
IL ll GetRoot(RG ll n){
RG ll tmp = n - 1 , tot = 0;
for(RG ll i = 2; i <= sqrt(tmp); i ++){
if(tmp%i==0){
prm[++tot] = i;
while(tmp%i==0)tmp /= i;
}
}
if(tmp != 1)prm[++tot] = tmp; //质因数分解
for(RG ll g = 2; g <= n-1; g ++){
bool flag = 1;
for(RG int i = 1; i <= tot; i ++){ //检测是否符合条件
if(Power(g,(n-1)/prm[i],n) == 1)
{ flag = 0; break; }
}
if(flag)return g;
}return 0; //无解
}
int main(){
cin >> N;
root = GetRoot(N);
cout<<root<<endl;
return 0;
}
g是mod(r * 2 ^ k + 1)的原根
r * 2 ^ k + 1 |
r |
k |
g |
3 |
1 |
1 |
2 |
5 |
1 |
2 |
2 |
17 |
1 |
4 |
3 |
97 |
3 |
5 |
5 |
193 |
3 |
6 |
5 |
257 |
1 |
8 |
3 |
7681 |
15 |
9 |
17 |
12289 |
3 |
12 |
11 |
40961 |
5 |
13 |
3 |
65537 |
1 |
16 |
3 |
786433 |
3 |
18 |
10 |
5767169 |
11 |
19 |
3 |
7340033 |
7 |
20 |
3 |
23068673 |
11 |
21 |
3 |
104857601 |
25 |
22 |
3 |
167772161 |
5 |
25 |
3 |
469762049 |
7 |
26 |
3 |
998244353 |
119 |
23 |
3 |
1004535809 |
479 |
21 |
3 |
2013265921 |
15 |
27 |
31 |
2281701377 |
17 |
27 |
3 |
3221225473 |
3 |
30 |
5 |
75161927681 |
35 |
31 |
3 |
77309411329 |
9 |
33 |
7 |
206158430209 |
3 |
36 |
22 |
2061584302081 |
15 |
37 |
7 |
2748779069441 |
5 |
39 |
3 |
6597069766657 |
3 |
41 |
5 |
39582418599937 |
9 |
42 |
5 |
79164837199873 |
9 |
43 |
5 |
263882790666241 |
15 |
44 |
7 |
1231453023109121 |
35 |
45 |
3 |
1337006139375617 |
19 |
46 |
3 |
3799912185593857 |
27 |
47 |
5 |
4222124650659841 |
15 |
48 |
19 |
7881299347898369 |
7 |
50 |
6 |
31525197391593473 |
7 |
52 |
3 |
180143985094819841 |
5 |
55 |
6 |
1945555039024054273 |
27 |
56 |
5 |
4179340454199820289 |
29 |
57 |
3 |