NC231471. 【模板】原根
描述
输入描述
第一行:一个整数 ,表示数据组数。
接下来 行:每行两个整数 ,表示一组询问数据。
,,
输出描述
对于每组数据:
第一行输出一个整数 ,表示 的原根个数,第二行输出 个数,按照题目描述中要求输出。
注意:即使 ,也需要输出一个空行。
示例1
输入:
6 2 1 4 1 25 2 36 1 9 6 18 1
输出:
1 1 1 3 8 3 12 17 23 0 2 2 5 11
说明:
对于第 组数据,给出的 的所有原根都出现在输出中。C++(g++ 7.5.0) 解法, 执行用时: 2391ms, 内存消耗: 3336K, 提交时间: 2022-09-16 22:25:29
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <vector> #define int long long using namespace std ; const int N = 1e6 + 5 ; int mod ; void read(int & x) { scanf("%lld" , &x) ; } void print(int x , char c = '\n') { printf("%lld%c" , x , c) ; } int qmi(int a , int b = mod - 2) { int res = 1; while (b) { if (b & 1) res = (long long)res * a % mod; a = (long long)a * a % mod , b >>= 1; } return res; } int n , m , d ; vector<int> q ; int ans[N] , idx ; vector<int> get(int n) { vector<int> ans; int t = n ; for (int i = 2 ; i * i <= t ; ++ i) { if (t % i == 0) { ans.push_back(i) ; while (t % i == 0) t /= i ; } } if (t > 1) ans.push_back(t) ; return ans ; } void solve() { cin >> n >> d ; mod = n ; idx = 0 , q = get(n) ; int Euler = n ; for (int p : q) Euler = Euler / p * (p - 1) ; q = get(Euler) ; int G = -1 ; for (int i = 1 ; i < n ; ++ i) { if (__gcd(i , n) != 1) continue; bool fg = 1 ; for (int p : q) { if (qmi(i , Euler / p) == 1) { fg = 0 ; break; } } if (fg) { G = i ; break; } } if (~G) for (int p = G , i = 1 ; i <= Euler ; p = p * G % mod , ++ i) if (__gcd(Euler , i) == 1) ans[++idx] = p ; sort(ans + 1 , ans + idx + 1) ; cout << idx << '\n' ; for (int i = d ; i <= idx || (puts("") , 0) ; i += d) printf("%d " , ans[i]) ; } signed main() { int t ; cin >> t ; while (t--) solve() ; return 0 ; }
C++ 解法, 执行用时: 1690ms, 内存消耗: 3992K, 提交时间: 2022-07-14 11:18:31
#include <bits/stdc++.h> using namespace std; typedef long long LL; LL ksm(LL a, LL b, LL mod) { LL ans = 1; while(b) { if(b & 1) ans = ans * a % mod; b >>= 1; a = a * a % mod; } return ans; } vector<int> get_gen(int x) { int m = x; int phi = x; for (int i = 2; i * i <= m; i ++ ) { if(m % i == 0) { phi = (LL)phi * (i-1) / i; while(m % i == 0) m /= i; } } if(m != 1) phi = (LL)phi * (m - 1) / m; vector<int> pfac; m = phi; for (int i = 2; i * i <= m; i ++ ) { if(m % i == 0) { pfac.push_back(i); while(m % i == 0) m /= i; } } if(m != 1) pfac.push_back(m); vector<int> res; for (int k = 1; k < x; k ++ ) { int f = 1; if(__gcd(k, x) != 1) continue; for (int i = 0; i < pfac.size(); i ++ ) { int xx = pfac[i]; if(ksm(k, phi / xx, x) == 1) { f = 0; break; } } if(f) { res.push_back(k); break; } } int len = res.size(); if(len) { int k = res[0]; res.pop_back(); for (int i = 1; i <= phi; i ++ ) if(__gcd(i, phi) == 1) res.push_back(ksm(k, i, x)); } return res; } int main() { int T; scanf("%d", &T); while(T -- ) { int x, d; scanf("%d%d", &x, &d); auto res = get_gen(x); sort(res.begin(), res.end()); int len = res.size(); printf("%d\n", len); for (int i = d; i <= len; i += d) { printf("%d ", res[i-1]); } puts(""); } }