題目大概意思就是c++
有幾對 \(i\) , \(j\) 知足 \((a_i+a_j)\) * \((a_i^2 + a_j^2)\) % \(p\) = \(k\) % \(p\)git
暴力的時間複雜度顯然是 \(θ(N^2)\) 的 , \(2 <= N <= 300000\) 顯然會 T 掉 而 CF T 掉是沒有部分分的spa
好咱們看 根據初中的數學知識
\[(a+b)(a-b) = a^2 - b^2\]code
當咱們看到 \((a_i+a_j)\) 確定會第一個想到\((a_i-a_j)\)get
因此兩邊同乘 \((a_i-a_j)\) , 而後根據柿子
可得
\[(a_i^2 + a_j^2)(a_i^2 - a_j^2)\%p = k(a_i-a_j)\%p\]數學
那麼再根據柿子
\[(a+b)(a-b) = a^2 - b^2\]
不難再次合併
可得
\[(a_i^4 - a_j^4) = k *a_i - k * a_j\]it
而後移項class
\[a_i^4 - a_i *k= a_j^4 - a_j *k\]test
如何\(\theta(N)\) 算出答案的值呢?map
int ans = 0 ; for(register int i=1;i<=n;i++) { ans += mp[f[i]] ; ++ mp[f[i]] ; }
記得多取模%%% + LL
#include <bits/stdc++.h> #define rep(i,j,n) for(register int i=j;i<=n;i++) #define Rep(i,j,n) for(register int i=j;i>=n;i--) #define low(x) x&(-x) using namespace std ; typedef long long LL ; const int inf = INT_MAX >> 1 ; inline LL read() { LL res(0) , f(1) ; register char c ; #define gc c = getchar() while(isspace(gc)) ; c == '-' ? f = - 1 , gc : 0 ; while(res = (res << 1) + (res << 3) + (c & 15) , isdigit(gc)) ; return res * f ; #undef gc } #define int long long int n , p , k ; int a[300000 + 5] ; int f[300000 + 5] ; map < int , int > mp ; inline void Ot() { n = read() , p = read() , k = read() ; for(register int i=1; i<=n; i++) a[i] = read() ; for(register int i=1; i<=n; i++) { f[i] = (a[i] * a[i]) % p * a[i] % p * a[i] % p - a[i] * k % p ; f[i] %= p ; if(f[i] < 0) f[i] += p ; } int ans = 0 ; for(register int i=1;i<=n;i++) { ans += mp[f[i]] ; ++ mp[f[i]] ; } cout << ans << endl ; return ; } signed main() { // freopen("test.in","r",stdin) ; return Ot() , 0 ; }