Codeforces914G Sum the Fibonacci(FWT)
阿新 • • 發佈:2019-01-04
FWT大雜燴。跟著模擬做很多次FWT即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N (1<<17) #define P 1000000007 int read() { int x=0,f=1;char c=getchar();while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,ab[N],c[N],de[N],f[N]; void OR(int *a,int n,int op) { for (int i=2;i<=n;i<<=1) for (int j=0;j<n;j+=i)for (int k=j;k<j+(i>>1);k++) { int x=a[k],y=a[k+(i>>1)]; a[k]=x;if (op==0) a[k+(i>>1)]=(y+x)%P;else a[k+(i>>1)]=(y-x+P)%P; } } void AND(int *a,int n,int op) { for (int i=2;i<=n;i<<=1) for (int j=0;j<n;j+=i)for (int k=j;k<j+(i>>1);k++) { int x=a[k],y=a[k+(i>>1)]; if (op==0) a[k]=(x+y)%P;else a[k]=(x-y+P)%P;a[k+(i>>1)]=y; } } void XOR(int *a,int n,int op) { for (int i=2;i<=n;i<<=1) for (int j=0;j<n;j+=i) for (int k=j;k<j+(i>>1);k++) { int x=a[k],y=a[k+(i>>1)]; a[k]=(x+y)%P,a[k+(i>>1)]=(x-y+P)%P; if (op) a[k]=1ll*a[k]*500000004%P,a[k+(i>>1)]=1ll*a[k+(i>>1)]*500000004%P; } } void FWT(int *a,int *b,int n,int op) { if (op==0) OR(a,n,0),OR(b,n,0); else if (op==1) AND(a,n,0),AND(b,n,0); else XOR(a,n,0),XOR(b,n,0); for (int i=0;i<n;i++) a[i]=1ll*a[i]*b[i]%P; if (op==0) OR(a,n,1),OR(b,n,1); else if (op==1) AND(a,n,1),AND(b,n,1); else XOR(a,n,1),XOR(b,n,1); } int main() { n=read(); while (n--) c[read()]++; memcpy(de,c,sizeof(de)); FWT(de,c,N,2); for (int i=0;i<N;i++) { for (int j=i;j;j=j-1&i) ab[i]=(ab[i]+1ll*c[j]*c[i^j]%P)%P; ab[i]=(ab[i]+1ll*c[i]*c[0])%P; } f[0]=0,f[1]=1;for (int i=2;i<N;i++) f[i]=(f[i-1]+f[i-2])%P; for (int i=0;i<N;i++) ab[i]=1ll*ab[i]*f[i]%P,c[i]=1ll*c[i]*f[i]%P,de[i]=1ll*de[i]*f[i]%P; FWT(ab,de,N,1);FWT(ab,c,N,1); int ans=0;for (int i=0;i<17;i++) ans=(ans+ab[1<<i])%P; cout<<ans; return 0; }