链接
http://acm.hdu.edu.cn/showproblem.php?pid=6128
题解
首先,我肯定要去掉原序列的所有
0
0
0
化简后,得到原条件的等价条件
a
i
2
+
a
j
2
+
a
i
a
j
=
0
a_i^2+a_j^2+a_ia_j=0
ai2+aj2+aiaj=0
然后我就卡住了,半天想不到直接去搜题解
有一个初中生都知道的公式
a
3
−
b
3
=
(
a
−
b
)
(
a
2
+
b
2
+
a
b
)
a^3-b^3=(a-b)(a^2+b^2+ab)
a3−b3=(a−b)(a2+b2+ab)
我给我我化简出的式子两边乘以
(
a
i
−
a
j
)
(a_i-a_j)
(ai−aj)
便得到
a
i
3
−
a
j
3
=
(
a
i
−
a
j
)
(
a
i
2
+
a
j
2
+
a
i
a
j
)
a_i^3-a_j^3=(a_i-a_j)(a_i^2+a_j^2+a_ia_j)
ai3−aj3=(ai−aj)(ai2+aj2+aiaj)
先统计有多少
a
i
3
=
a
j
3
a_i^3=a_j^3
ai3=aj3的
(
i
,
j
)
(i,j)
(i,j)
a
i
3
−
a
j
3
=
0
a_i^3-a_j^3=0
ai3−aj3=0是原命题成立的必要不充分条件
因此要研究多算了哪些,最后减去这个数目
注意
(
a
i
−
a
j
)
(
a
i
2
+
a
j
2
+
a
i
a
j
)
=
0
(a_i-a_j)(a_i^2+a_j^2+a_ia_j)=0
(ai−aj)(ai2+aj2+aiaj)=0
这个成立有三种可能:
a
i
−
a
j
=
0
a_i-a_j=0
ai−aj=0且
a
i
2
+
a
j
2
+
a
i
a
j
=
0
a_i^2+a_j^2+a_ia_j=0
ai2+aj2+aiaj=0
a
i
−
a
j
=
0
a_i-a_j=0
ai−aj=0且
a
i
2
+
a
j
2
+
a
i
a
j
=
̸
0
a_i^2+a_j^2+a_ia_j=\not 0
ai2+aj2+aiaj≠0
a
i
−
a
j
=
̸
0
a_i-a_j=\not 0
ai−aj≠0且
a
i
2
+
a
j
2
+
a
i
a
j
=
0
a_i^2+a_j^2+a_ia_j=0
ai2+aj2+aiaj=0
要减去的便是上述第二种情况
当
a
i
−
a
j
=
0
a_i-a_j=0
ai−aj=0时,设
a
i
=
a
j
=
t
a_i=a_j=t
ai=aj=t
则
a
i
2
+
a
j
2
+
a
i
a
j
=
3
t
2
a_i^2+a_j^2+a_ia_j=3t^2
ai2+aj2+aiaj=3t2
3
t
2
3t^2
3t2在模
p
p
p意义下不等于
0
0
0便意味着
3
t
2
3t^2
3t2不是
p
p
p的倍数
注意到
p
p
p是素数而且
t
<
p
t<p
t<p,因此
t
2
t^2
t2中不含有
p
p
p的倍数
那么只有
p
=
3
p=3
p=3的时候,才可能
3
t
2
=
0
3t^2=0
3t2=0
当
p
=
̸
3
p=\not3
p≠3时,必有
a
i
=
a
j
⇒
a
i
2
+
a
j
2
+
a
i
a
j
a_i=a_j\Rightarrow a_i^2+a_j^2+a_ia_j
ai=aj⇒ai2+aj2+aiaj,要减去这些
代码
#include <bits/stdc++.h>
#define maxn 100010
using namespace std;
typedef long long ll;
struct EasyMath
{
ll fastpow(ll a, ll b, ll c)
{
ll t(a%c), ans(1ll);
for(;b;b>>=1,t=mult(t,t,c))if(b&1)ans=mult(ans,t,c);
return ans;
}
ll mult(ll a, ll b, ll c)
{
ll t(a%c), ans(0ll);
for(;b;b>>=1,(t+=t)%=c)if(b&1)(ans+=t)%=c;
return ans;
}
}math;
ll a[maxn];
map<ll,ll> tb1, tb3;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return f*x;
}
int main()
{
ll T(read()), n, p, i;
while(T--)
{
n=read(), p=read();
tb1.clear(), tb3.clear();
for(i=1;i<=n;i++)
{
auto a=read();
if(a==0)continue;
tb1[a]++;
tb3[math.mult(math.mult(a,a,p),a,p)]++;
}
ll ans(0);
for(auto pr:tb3)ans+=pr.second*(pr.second-1)/2;
if(p!=3)
{
for(auto pr:tb1)ans-=pr.second*(pr.second-1)/2;
}
cout<<ans<<endl;
}
return 0;
}