题目链接

http://www.spoj.com/problems/SWERC14C/

思路

FFT半裸题了。
如果一个多项式有xi项,另一个多项式有xj项,那么相乘后的多项式就一定有xi+j项。
那么如果读入一个数i,那么多项式xi项就赋值为1
最后把多项式平方,得出多项式次数为哪些时,系数有值,说明这个次数能被凑出来。

代码

#include <cstdio>
#include <cmath>
#include <algorithm>

const int maxn=200000;
const double pi=acos(-1);

struct complex
{
  double r,i;

  complex(double r_=0,double i_=0)
  {
    r=r_;
    i=i_;
  }

  complex operator +(const complex &other) const
  {
    return complex(r+other.r,i+other.i);
  }

  complex operator -(const complex &other) const
  {
    return complex(r-other.r,i-other.i);
  }

  complex operator *(const complex &other) const
  {
    return complex(r*other.r-i*other.i,r*other.i+i*other.r);
  }
};

complex a[maxn<<2];
int rev[maxn<<2],n,m,ans;

int fft(complex* ar,int len,int op)
{
  for(register int i=0; i<len; ++i)
    {
      if(rev[i]<i)
        {
          std::swap(ar[rev[i]],ar[i]);
        }
    }
  for(register int i=2; i<=len; i<<=1)
    {
      complex wn(cos(2*pi/i),sin(2*pi*op/i));
      for(register int j=0; j<len; j+=i)
        {
          complex w(1,0);
          for(register int k=0; k<(i>>1); ++k)
            {
              complex x=ar[j+k],y=w*ar[j+k+(i>>1)];
              ar[j+k]=x+y;
              ar[j+k+(i>>1)]=x-y;
              w=w*wn;
            }
        }
    }
  if(op==-1)
    {
      for(register int i=0; i<len; ++i)
        {
          ar[i].r/=len;
        }
    }
  return 0;
}

inline int calc(int x)
{
  int l=0;
  m=1;
  while(m<=x)
    {
      m<<=1;
      ++l;
    }
  for(register int i=0; i<m; ++i)
    {
      rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
    }
  return 0;
}

int main()
{
  scanf("%d",&n);
  for(register int i=1; i<=n; ++i)
    {
      int w;
      scanf("%d",&w);
      a[w].r=1;
    }
  a[0]=1;
  calc(maxn<<1);
  fft(a,m,1);
  for(register int i=0; i<m; ++i)
    {
      a[i]=a[i]*a[i];
    }
  fft(a,m,-1);
  scanf("%d",&n);
  for(register int i=1; i<=n; ++i)
    {
      int w;
      scanf("%d",&w);
      if(a[w].r-0.5>0)
        {
          ++ans;
        }
    }
  printf("%d\n",ans);
  return 0;
}