题解:AT_abc392_g [ABC392G] Fine Triplets
题意
给你一个大小为
思路
设集合中某个数
其中
设
我们规定
不难发现
因为任意一个在集合中出现的元素
设
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5,mod=998244353,g=3;//998244353=(2^23)*7*17
int fpow(int n,int k=mod-2)//快速幂
{
int res=1,base=n;
for(;k>0;k>>=1)
{
if((k&1)==1)res=1ll*res*base%mod;
base=1ll*base*base%mod;
}
return res;
}
const int invg=fpow(g);
int rev[N<<2];
void NTT(int*a,int len,bool inv) //NTT
{
for(int i=0;i<len;i++)
if(i<rev[i])swap(a[i],a[rev[i]]);
for(int mid=1;mid<len;mid<<=1)
{
int wn=fpow(inv?invg:g,(mod-1)/(mid<<1));
for(int i=0;i<len;i+=mid<<1)
{
int wk=1;
for(int j=i;j<i+mid;j++,wk=1ll*wk*wn%mod)
{
int x=a[j],y=1ll*wk*a[j+mid]%mod;
a[j]=(x+y)%mod,a[j+mid]=(x-y+mod)%mod;
}
}
}
}
void times(int n,int m,int*a,int*b) //计算多项式相乘的系数
{
int len=1,cnt=0;
while(len<=n+m)len<<=1,cnt++;
for(int i=1;i<len;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<cnt-1);
NTT(a,len,false),NTT(b,len,false);
for(int i=0;i<len;i++)a[i]=1ll*a[i]*b[i]%mod;
NTT(a,len,true);
for(int i=0;i<len;i++)a[i]=1ll*a[i]*fpow(len)%mod;
}
int a[N<<2],b[N<<2],x[N];
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>x[i],a[x[i]]++,b[x[i]]++;
times(1e6,1e6,a,b);
ll ans=0;
for(int i=1;i<=n;i++)ans+=a[2*x[i]]; //统计答案
cout<<(ans-n)/2;
return 0;
}