hdu 6128 Inverse of sum(推公式)

题目链接:hdu 6128 Inverse of sum

题意:

给你n个数,问你有多少对i,j,满足i<j,并且1/(ai+aj)=1/ai+1/a在%p意义下。

题解:

不愧是高中生,推公式神题。

将式子通分化简后可得(ai2+aj2+ai*aj)%p=0。

然后两边同时将两边乘(ai-aj),化简可得(ai3-aj3)%p=0。

然后就可以用map记录一下个数,并且减掉ai==aj时不合法的情况就行了。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 3 using namespace std;
 4 typedef long long ll;
 5 
 6 const int N=1e5+7;
 7 int t,n;
 8 ll p,a[N];
 9 map<ll,int>hsh;
10 map<ll,int>cnt;
11 
12 ll mul(ll a,ll b)
13 {
14     ll an=0;
15     while(b)
16     {
17         if(b&1)an=(an+a)%p;
18         b>>=1,a=(a+a)%p;
19     }
20     return an;
21 }
22 
23 int main()
24 {
25     scanf("%d",&t);
26     while(t--)
27     {
28         scanf("%d%lld",&n,&p);
29         hsh.clear();
30         cnt.clear();
31         ll ans=0;
32         F(i,1,n)
33         {
34             scanf("%lld",a+i);
35             if(!a[i])continue;
36             if(mul(mul(a[i],a[i]),3))ans-=cnt[a[i]];
37             ll tp=mul(mul(a[i],a[i]),a[i]);
38             ans+=hsh[tp]++;
39             ++cnt[a[i]];
40         }
41         printf("%lld
",ans);
42     }
43     return 0;
44 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/7367337.html