hdu6128 Inverse of sum

本文提供了一道编号为6128的HDU在线评测题目解析,通过对原始条件进行数学变形,利用立方差公式,将问题转化为求特定条件下元素对的数量。特别考虑了模意义下特殊情况的排除。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接

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) a3b3=(ab)(a2+b2+ab)
我给我我化简出的式子两边乘以 ( a i − a j ) (a_i-a_j) (aiaj)
便得到 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) ai3aj3=(aiaj)(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 ai3aj3=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 (aiaj)(ai2+aj2+aiaj)=0
这个成立有三种可能:
a i − a j = 0 a_i-a_j=0 aiaj=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 aiaj=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 aiaj≠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 aiaj=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 &lt; p t&lt;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=ajai2+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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值