给你一个质数 $P$。求点对 $(x, y), x, y \in [0, P - 1]$ 的点对数量。
其中 $x^k \equiv y \pmod P$。
可以想到如果能把指数拿下来会就变成一个乘积的形式,那么能将指数取下来的情况也就是底数相同。题目中给定的是一个素数 $P$。这也就是意味着其缩系的大小就是 $P - 1$。然后质数的原根也就是 $P - 1$。能表示题目中的任意数。
那么我们可以转换到 $g^{ka} \equiv g^b \pmod P$ 我们就可以把指数取下来。得到 $ka \equiv b \pmod {P - 1}$。我们把形式转换一下得到 $ka - y(P - 1) = b$。
根据 $\tt Lucas$ 定理这个方程有解的条件就是 $b | \gcd(a, P - 1)$。
这边可以将 $k$ 当成 $x$ 会更加显然。
那么 $b$ 的数量就是 $\frac{P - 1}{\gcd(a, P - 1)}$。
做法 $1$:
那么可以得到柿子 $\sum_{i = 1} ^ {P - 1} \frac{P -1} {i} \times \varphi(\frac{P - 1}i)$。
我们考虑原来的柿子是这样的 $\sum_{i = 1} ^ {P- 1} \frac{P - 1}{\gcd(i, P - 1)}$。我们考虑枚举公约数,考虑被计算了几次。
$\sum_{i = 1} ^ {P - 1} \frac{P - 1}{i} \times |S|$,其中 $\forall a \in S, i = \gcd(a, P -1)$ 那么也意味着 $1 = \gcd(\frac{a}{i}, \frac{P -1}{i})$ 也就是求和 $\frac{P - 1}{i}$ 互质的数的个数,就是 $\varphi(\frac{P - 1}i)$。
做法 $2$:
考虑进行反演。 $$ \begin{aligned} &\sum_{i = 1} ^ {P - 1} \frac{P - 1}{\gcd(i, P - 1)} \ =& (P - 1) \sum_{i = 1} ^ {P - 1} \sum_{d = 1} ^ {P - 1} \frac{1}{d} [\gcd(\frac{i}{d}, \frac{P - 1}{d}) = 1]\ = &\sum_{d | (P - 1)} ^{P - 1} \frac{1}{d}\sum_{d | i} ^{P - 1} \varphi(\frac{P - 1}{d}) \ = &\sum_{d | (P - 1)} ^ {P - 1} \frac{1}{d} \lfloor\frac{P -1}{d}\rfloor \times \varphi(\frac{P - 1}{d}) \ \end{aligned} $$ 这边同样可以得到答案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 #include <bits/stdc++.h> using namespace std;#ifdef Fread char buf[1 << 21 ], *iS, *iT;#define gc() (iS == iT ? (iT = (iS = buf) + fread (buf, 1, 1 << 21, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++) #define getchar gc #endif template <typename T>void r1 (T &x) { x = 0 ; char c (getchar()) ; int f (1 ) ; for (; c < '0' || c > '9' ; c = getchar ()) if (c == '-' ) f = -1 ; for (; '0' <= c && c <= '9' ;c = getchar ()) x = (x * 10 ) + (c ^ 48 ); x *= f; } #ifdef Getmod const int mod = 1e9 + 7 ;template <int mod>struct typemod { int z; typemod (int a = 0 ) : z (a) {} inline int inc (int a,int b) const {return a += b - mod, a + ((a >> 31 ) & mod);} inline int dec (int a,int b) const {return a -= b, a + ((a >> 31 ) & mod);} inline int mul (int a,int b) const {return 1ll * a * b % mod;} typemod<mod> operator + (const typemod<mod> &x) const {return typemod (inc (z, x.z));} typemod<mod> operator - (const typemod<mod> &x) const {return typemod (dec (z, x.z));} typemod<mod> operator * (const typemod<mod> &x) const {return typemod (mul (z, x.z));} typemod<mod>& operator += (const typemod<mod> &x) {*this = *this + x; return *this ;} typemod<mod>& operator -= (const typemod<mod> &x) {*this = *this - x; return *this ;} typemod<mod>& operator *= (const typemod<mod> &x) {*this = *this * x; return *this ;} int operator == (const typemod<mod> &x) const {return x.z == z;} int operator != (const typemod<mod> &x) const {return x.z != z;} }; typedef typemod<mod> Tm;#endif template <typename T,typename ... Args> inline void r1 (T& t, Args&... args) { r1 (t); r1 (args...); } #define int long long const int maxn = 2e5 + 5 ;const int maxm = maxn << 1 ;int P;vector<int > s; const int mod = 998244353 ;int getphi (int x) { int res (x) ; for (int i = 2 ; i * i <= x; ++ i) if (x % i == 0 ) { res = res / i * (i - 1 ); while (x % i == 0 ) x /= i; } if (x > 1 ) res = res / x * (x - 1 ) ; return res % mod; } signed main () { int i; r1 (P); for (i = 1 ; i * i <= P - 1 ; ++ i) if ((P - 1 ) % i == 0 ) { s.push_back (i); if (i * i != (P - 1 )) s.push_back ((P - 1 ) / i); } int ans (0 ) ; for (int v : s) { ans += (P - 1 ) / v % mod * getphi ((P - 1 ) / v) % mod; ans %= mod; } ans = (ans + 1 ) % mod; printf ("%lld\n" , ans); return 0 ; }