zoukankan      html  css  js  c++  java
  • CF914G Sum the Fibonacci(FWT,FST)

    CF914G Sum the Fibonacci(FWT,FST)

    Luogu

    题解时间

    一堆FWT和FST缝合而来的丑陋产物。

    对 $ cnt[s_{a}] $ 和 $ cnt[s_{b}] $ 求FST,对 $ cnt[s_{d}] $ 和 $ cnt[s_{e}] $ 求异或卷积,然后对 $ cnt[ s_{ a }| s_{ b } ] imes f[ s_{ a }| s_{ b } ] $ , $ cnt[ s_{ c } ] imes f[ s_{ c } ] $ , $ cnt[ s_{ d } oplus s_{ e } ] imes f[ s_{ d } oplus s_{ e } ] $ 求与卷积,将每个 $ 2^{i} $ 项的答案加起来就完事。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long lint;
    struct pat{int x,y;pat(int x=0,int y=0):x(x),y(y){}bool operator<(const pat &p)const{return x==p.x?y<p.y:x<p.x;}};
    template<typename TP>inline void read(TP &tar)
    {
    	TP ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){ret=ret*10+(ch-'0');ch=getchar();}
    	tar=ret*f;
    }
    namespace RKK
    {
    const int N=18,S=1<<17;
    const int mo=1000000007,inv2=500000004;
    int bcnt(int x){return __builtin_popcount(x);}
    int lbit(int x){return __builtin_ffs(x);}
    int add(int a,const int &b){a+=b;if(a>=mo) a-=mo;else if(a<0) a+=mo;return a;}
    void doadd(int &a,const int &b){a+=b;if(a>=mo) a-=mo;else if(a<0) a+=mo;}
    void fwtand(int *a,int len,int tp)
    {
    	for(int i=1;i<len;i<<=1)for(int j=0;j<len;j+=i<<1)for(int k=0;k<i;k++)
    		doadd(a[j+k],tp*a[j+k+i]);
    }
    void fwtor(int *a,int len,int tp)
    {
    	for(int i=1;i<len;i<<=1)for(int j=0;j<len;j+=i<<1)for(int k=0;k<i;k++)
    		doadd(a[j+k+i],tp*a[j+k]);
    }
    void fwtxor(int *a,int len,int tp)
    {
    	int x,y;
    	for(int i=1;i<len;i<<=1)for(int j=0;j<len;j+=i<<1)for(int k=0;k<i;k++)
    	{
    		x=a[j+k],y=a[j+k+i];
    		a[j+k]=add(x,y),a[j+k+i]=add(x,-y);
    		if(tp==-1) a[j+k]=(lint)a[j+k]*inv2%mo,a[j+k+i]=(lint)a[j+k+i]*inv2%mo;
    	}
    }
    int n,mxlen=1,mxlog,mxa,bc[S];
    int f[N][S],g[S];
    int a[S],b[S],c[S],fib[S];
    int main()
    {
    	fib[0]=0,fib[1]=1;for(int i=2;i<S;i++) fib[i]=add(fib[i-1],fib[i-2]);
    	for(int i=1;i<S;i++) bc[i]=bcnt(i);
    	read(n);for(int i=1,w;i<=n;i++)
    		read(w),mxa=max(mxa,w),f[bc[w]][w]++,a[w]++,doadd(b[w],fib[w]);
    	while(mxlen<=mxa) mxlen<<=1,mxlog++;
    	for(int i=0;i<=mxlog;i++) fwtor(f[i],mxlen,1);
    	for(int i=0;i<=mxlog;i++)
    	{
    		memset(g,0,mxlen*4);
    		for(int j=0;j<=i;j++)for(int s=0;s<mxlen;s++) doadd(g[s],1ll*f[j][s]*f[i-j][s]%mo);
    		fwtor(g,mxlen,-1);
    		for(int s=0;s<mxlen;s++)if(bc[s]==i) doadd(c[s],g[s]);
    	}
    	fwtxor(a,mxlen,1);for(int i=0;i<mxlen;i++) a[i]=1ll*a[i]*a[i]%mo;fwtxor(a,mxlen,-1);
    	for(int i=0;i<mxlen;i++) a[i]=1ll*a[i]*fib[i]%mo;
    	for(int i=0;i<mxlen;i++) c[i]=1ll*c[i]*fib[i]%mo;
    	fwtand(a,mxlen,1),fwtand(b,mxlen,1),fwtand(c,mxlen,1);for(int i=0;i<mxlen;i++) c[i]=1ll*a[i]*b[i]%mo*c[i]%mo;fwtand(c,mxlen,-1);
    	int ans=0;for(int i=1;i<mxlen;i<<=1) doadd(ans,c[i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    }
    int main(){return RKK::main();}
    
  • 相关阅读:
    POJ
    POJ
    BZOJ
    HDU
    codeforces
    BZOJ
    SPOJ
    SPOJ
    SPOJ
    HDU
  • 原文地址:https://www.cnblogs.com/rikurika/p/13330869.html
Copyright © 2011-2022 走看看