题面
题意:
现在有一个长度为 n n n的数组 a a a,找出有多少对 ( i , j ) (i,j) (i,j)满足 1 ≤ 1\leq 1≤ i < j i<j i<j ≤ n \leq n ≤n并且 ( a i + a j ) ∗ ( a i 2 + a j 2 ) m o d p = = k (a_i+a_j)*(a_i^{2}+a_j^{2})modp==k (ai+aj)∗(ai2+aj2)modp==k。
思路:
左右同乘
(
a
i
−
a
j
)
(a_i-a_j)
(ai−aj),则式子化为
(
a
i
4
−
a
j
4
)
m
o
d
(a_i^{4}-a_j^{4})mod
(ai4−aj4)mod
p
=
=
p==
p==
k
∗
(
a
i
−
a
j
)
k*(a_i-a_j)
k∗(ai−aj)
m
o
d
mod
mod
p
p
p
移项得:
(
a
i
4
−
k
∗
a
i
)
(a_i^{4}-k*a_i)
(ai4−k∗ai)
m
o
d
mod
mod
p
=
=
p==
p==
(
a
j
4
−
k
∗
a
j
)
(a_j^{4}-k*a_j)
(aj4−k∗aj)
m
o
d
mod
mod
p
p
p .
因此我们至于要统计每个
(
a
i
4
−
k
∗
a
i
)
(a_i^{4}-k*a_i)
(ai4−k∗ai)
m
o
d
mod
mod
p
p
p出现的次数,再累加即可,
m
a
p
map
map和
s
e
t
set
set可以
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n))的解决这个问题。
#include<bits/stdc++.h>
using namespace std;
set<long long > s;
map<long long ,long long > mmp;
int main(){
long long n,p,x,k;
cin>>n>>p>>k;
for(int i=1;i<=n;i++){
cin>>x;
mmp[((x%p*x%p*x%p*x%p)%p-(k%p*x%p)+p)%p]++;
s.insert(((x%p*x%p*x%p*x%p)%p-(k%p*x%p)%p+p)%p);
}
long long ans=0;
for(long long v:s){
ans+=(mmp[v]*(mmp[v]-1)/2);
}
cout<<ans<<endl;
return 0;
}