题目大概意思就是
有几对 \(i\) , \(j\) 满足 \((a_i+a_j)\) * \((a_i^2 + a_j^2)\) % \(p\) = \(k\) % \(p\)
这样做 时间复杂度显然是 \(θ(N^2)\) 的
\(2 <= N <= 300000\)
好我们看 根据初中的数学知识
\((a+b)(a-b) = a^2 - b^2\)
两边同乘 \((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\)
然后移项
\(a_i^4 - a_i *k\) = \(a_j^4 - a_j *k\)
所以说我们预处理出值就可以了然后顺带一提 如何\(\theta(N)\) 算出答案的值
int ans = 0 ;
for(register int i=1;i<=n;i++) {
ans += mp[f[i]] ;
++ mp[f[i]] ;
}
代码其实不难写 记得多取模%%%
#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 ;
}