吧a数组的值当多向式的系数,跑fft,就可以知道某一个值有多少种另外两个值组成他的方案
i,j,k不能相同,那么对于每一个ai+ai=aj,先减掉再说
ai+0=ai , 0+ai=ai, 那么不管这个ai是否是0,aj=0时会造成不合法情况,那么对于每一个aj=0,由于已经保证i!=j,那么会使得1-n中除j之外的所有ai都多算两种不合法情况,即2*(n-1)种情况,那么一共就多出2*num[0+maxl]*(n-1)种情况。
数组开小结果WA了,调一下午= =
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxl 50000
#define mi 274000
using namespace std;
const double pi=acos(-1.0);
long long n,len,mx;
long long a[mi],num[mi];
long long c[mi];
long long ans;
struct complex
{
double r,i;
complex(double r1=0.0,double i1=0.0)
{
r=r1;i=i1;
}
complex operator + (const complex &b)
{
return complex(r+b.r,i+b.i);
}
complex operator - (const complex &b)
{
return complex(r-b.r,i-b.i);
}
complex operator * (const complex &b)
{
return complex(r*b.r-i*b.i,r*b.i+i*b.r);
}
}x1[mi],x2[mi],x[mi];
inline void prework()
{
memset(x1,0,sizeof(x1));
mx=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
num[a[i]+maxl]++;
x1[a[i]+maxl].r+=1;
mx=max(mx,a[i]+maxl);
}
}
void change(complex y[],int len)
{
int i,j;
for(i=1,j=len/2;i<len-1;i++)
{
if(i<j)
swap(y[i],y[j]);
int k=len/2;
while(j>=k)
j-=k,k/=2;
if(j<k)
j+=k;
}
}
void fft(complex y[],int len,int on)
{
change(y,len);
for(int l=2;l<=len;l<<=1)
{
complex wn(cos(-on*2*pi/l),sin(-on*2*pi/l));
for(int j=0;j<len;j+=l)
{
complex w(1,0);
for(int k=j;k<j+l/2;k++)
{
complex u=y[k];
complex t=w*y[k+l/2];
y[k]=u+t;
y[k+l/2]=u-t;
w=w*wn;
}
}
}
if(on==-1)
for(int i=0;i<len;i++)
y[i].r/=len;
}
inline void mainwork()
{
len=1;
while(len<2*mx)
len<<=1;
memset(x,0,sizeof(x));
fft(x1,len,1);
for(int i=0;i<len;i++)
x[i]=x1[i]*x1[i];
fft(x,len,-1);
for(int i=0;i<len;i++)
c[i]=(long long)(x[i].r+0.5);
for(int i=1;i<=n;i++)
c[2*(a[i]+maxl)]--;
ans=0;
for(int i=1;i<=n;i++)
ans+=c[a[i]+2*maxl];
ans-=2*num[maxl]*(n-1);
}
inline void print()
{
printf("%lld\n",ans);
}
int main()
{
prework();
mainwork();
print();
return 0;
}
本文深入探讨了快速傅立叶变换(FFT)算法在解决特定数学问题中的应用,通过将数组值作为多向式系数,利用FFT算法计算特定值的组合方案。详细介绍了算法的实现过程,包括预处理、主要工作流程及最终结果输出,同时提到了数组大小调整的重要性。
528

被折叠的 条评论
为什么被折叠?



