FWT

  void FWT(LL a[],int len,int typ){
      LL mo,rev;
      if (typ==1) mo=mo1,rev=rev1;else mo=mo2,rev=rev2;
      for (int d=1;d<len;d<<=1)
        for (int i=0;i<len;i+=d*2)
          for (int j=0;j<d;j++){
            LL x=a[i+j],y=a[i+j+d];
          a[i+j]=(x+y)%mo;
          a[i+j+d]=(x-y+mo)%mo;    
                //xor:a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod;    
                //and:a[i+j]=x+y;    
                //or:a[i+j+d]=x+y;    
        }    
  }
  
  void UFWT(LL a[],int len,int typ){
      LL mo,rev;
      if (typ==1) mo=mo1,rev=rev1;else mo=mo2,rev=rev2;
      for (int d=1;d<len;d<<=1)
        for (int i=0;i<len;i+=d*2)
          for (int j=0;j<d;j++){
            LL x=a[i+j],y=a[i+j+d];
          a[i+j]=(x+y)*rev%mo;
          a[i+j+d]=((x-y)*rev%mo+mo)%mo;
                 //xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2;    
                //and:a[i+j]=x-y;    
                //or:a[i+j+d]=y-x;    
        }    
  }            

 ----------------------------------------------------------------------------------------------------------------------------------------

考虑以下问题

ck=sigma(ai*bj),k=i|j,i&j=0

也就是不相交集合并。

可以将该问题的转移条件改为k=i|j,popcount(i)+popcount(j)=popcount(k)

于是我们可以将FWT的元素用多项式代替。若a数组的第i位有ai的值,则a位置的初始多项式为ai*x^popcount(i)。

FWT结果中第i位上x^popcount(i)的系数即为第i位的答案

原文地址:https://www.cnblogs.com/zhujiangning/p/6554416.html