题目大意:给定一个长为$n$($n\leq 10^6$)的序列S,定义一个合法的五元组$(a,b,c,d,e)$合法当且仅当

$$ ( S_a \mid S_b ) and S_c and ( S_d \bigotimes S_e ) = 2^k $$

$$ S_a and S_b = 0 $$

对于所有的合法的五元组,求 $ \sum_{合法(a,b,c,d,e)}\  F( S_a \mid S_b ) \times F( S_c ) \times F( S_d \bigotimes S_e ) $

其中$F(i)$表示斐波那契数列第i项  $F(1)=0,F(2)=1$

$S_i\leq 2^{17}$ ,答案对1e9+7取模。

先放一篇大佬的博客,我理解这道题的方式以及本文的思维方法都对该文略有参考。

https://blog.csdn.net/BeNoble_/article/details/79512236

看到这道题,看到应该想到对于一个五元组$(a,b,c,d,e)$,abcde具体的值并没有意义,真正有意义的是S中的值,所以我们不记录S[],而是记录t[]表示每个数的数量。

然后,我们显然可以把式子分成三个部分:

左侧   $j and k==0\bigcap j\mid k==i$ 意义下多项式的卷积

中间   多项式

右侧   $\sum_{[j\bigotimes k==i]}$ 意义下的卷积

合并之前,我们可以直接对每个部分的多项式的每个位置乘上对应的斐波那契序列值,然后合并,最后统计答案。

步骤:

1、求左侧部分的卷积

2、对中间部分赋值

3、求右侧部分的卷积

4、合并三个部分,枚举每一个2的k次方项累计答案

其中,步骤2最为简易,直接枚举数组位置一个接一个赋值就行,步骤3,4都可以用FWT即快速沃尔什(逆)变换解决,而第一步就需要一点智慧了(详见2015vfk集训队论文)。

我们将 j|k==i&&j&k==0 的条件转化为 $j|k==i$&&$|j|+|k|==|i|$,其中$|x|$表示x二进制下1的个数。于是,我们对于每一个$|x|$记录一个数组p,把原来的数$t[x]$放到$p[|x|][x]$中,然后对于每一层$|x|$进行$j|k==i$意义下的卷积。然后令$g[|x|][i]=\sum_{j+k=|x|} p[j][i] + p[k][i]$,再将每一层|x|进行一次逆变换,最后,对于每一个pos,将$g[|pos|][pos]$提出来乘以相应位置的斐波那契序列值形成一个新的数组,里面存的就是我们要的第一步的卷积了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define mid (l+r>>1)
#define mod 1000000007ll
#define inv2 (mod+1>>1)
#define M 525000ll
#define OR 1ll
#define AND 2ll
#define XOR 3ll
using namespace std;
LL read(){
LL nm=0,fh=1;char cw=getchar();
for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
void write(LL x){
if(x<0){putchar('-');return write(-x);}
if(x>9) write(x/10);
putchar(x%10+'0');
} LL n,m,A[M],B[M],C[M],len,ans[M],bt[M],fib[M],maxn,top;
LL p[18][M],R[18][M],tt,t[M];
LL tk[M],h[M],w[M]; LL add(LL x,LL y){return (x+y+mod+mod)%mod;}
LL mul(LL x,LL y){return ((x*y%mod)+mod)%mod;}
void FWT(LL *x,LL tpe,LL kd){
for(LL tot=1;tot<len;tot<<=1){
for(LL st=0;st<len;st+=(tot<<1)){
for(LL pos=st;pos<st+tot;pos++){
LL t1=x[pos],t2=x[pos+tot];
if(tpe==OR) x[pos]=t1,x[pos+tot]=add(t1*kd,t2);
if(tpe==AND) x[pos]=add(t1,kd*t2),x[pos+tot]=t2;
if(tpe==XOR){
if(kd==1) x[pos]=add(t1,t2),x[pos+tot]=add(t1,-t2);
else x[pos]=mul(add(t1,t2),inv2),x[pos+tot]=mul(add(t1,-t2),inv2);
}
}
}
}
}
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n=read(),fib[0]=0,fib[1]=1;
for(LL i=2;i<M;i++) fib[i]=add(fib[i-1],fib[i-2]);
//calculate fibonacci for(LL i=1;i<M;i++) bt[i]=bt[i-(i&-i)]+1;
//calculate Bit_count for(LL i=1;i<=n;i++) m=read(),t[m]++,maxn=max(maxn,m);
//Trun --> a1,a2,a3 into --> sumof(1) sumof(2)... at t[] for(len=1;len<=maxn;len<<=1) top++;
for(LL i=0;i<len;i++) h[i]=t[i],p[bt[i]][i]=t[i];
//create new array of t[] initialize p(i,j) for(LL i=0;i<=top;i++) FWT(p[i],OR,1ll);
for(LL i=0;i<=top;i++){
for(LL j=0;j+i<=top;j++){
for(LL pos=0;pos<len;pos++) R[i+j][pos]=add(R[i+j][pos],mul(p[i][pos],p[j][pos]));
}
}
for(LL i=0;i<=top;i++) FWT(R[i],OR,-1ll);
//GET p(i,j): Sigma Bitcount=i for(LL i=0;i<len;i++) B[i]=mul(t[i],fib[i]);
//GET Bi : fib[i]*t[i] FWT(h,XOR,1ll);
for(LL i=0;i<len;i++) C[i]=mul(h[i],h[i]);
FWT(C,XOR,-1ll);
for(LL i=0;i<len;i++) C[i]=mul(C[i],fib[i]);
//GET: Ci : fib[i]* ( Sgm j^k==i t[j]*t[k] ) for(LL i=0;i<len;i++) A[i]=mul(fib[i],R[bt[i]][i]);
//GET Ai : fib[i]* Sgm j|k==i&&|j|+|k|==|i| t[j]*t[k] FWT(A,AND,1ll),FWT(B,AND,1ll),FWT(C,AND,1ll);
//FWT to A,B,C for(LL i=0ll;i<len;i++) ans[i]=mul(A[i],mul(B[i],C[i]));
FWT(ans,AND,-1ll);
//FWT to A*B*C --> ans --> UFWT ans for(LL i=1ll;i<len;i<<=1) tt=add(tt,ans[i]);
write(tt);
//print answer return 0;
}

codeforces914G Sum the Fibonacci的更多相关文章

  1. Codeforces914G Sum the Fibonacci(FWT)

    FWT大杂烩.跟着模拟做很多次FWT即可. #include<iostream> #include<cstdio> #include<cmath> #include ...

  2. 【CF914G】Sum the Fibonacci 快速??变换模板

    [CF914G]Sum the Fibonacci 题解:给你一个长度为n的数组s.定义五元组(a,b,c,d,e)是合法的当且仅当: 1. $1\le a,b,c,d,e\le n$2. $(s_a ...

  3. CF914G Sum the Fibonacci(FWT,FST)

    CF914G Sum the Fibonacci(FWT,FST) Luogu 题解时间 一堆FWT和FST缝合而来的丑陋产物. 对 $ cnt[s_{a}] $ 和 $ cnt[s_{b}] $ 求 ...

  4. 【codeforces914G】Sum the Fibonacci FWT+FST(快速子集变换)

    题目描述 给出一个长度为 $n$ 的序列 $\{s\}$ ,对于所有满足以下条件的五元组 $(a,b,c,d,e)$ : $1\le a,b,c,d,e\le n$ : $(s_a|s_b)\& ...

  5. Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined)G. Sum the Fibonacci

    题意:给一个数组s,求\(f(s_a | s_b) * f(s_c) * f(s_d \oplus s_e)\),f是斐波那契数列,而且要满足\(s_a\&s_b==0\),\((s_a | ...

  6. CF 914 G Sum the Fibonacci —— 子集卷积,FWT

    题目:http://codeforces.com/contest/914/problem/G 其实就是把各种都用子集卷积和FWT卷起来算即可: 注意乘 Fibonacci 数组的位置: 子集卷积时不能 ...

  7. 题解 CF914G Sum the Fibonacci

    题目传送门 题目大意 给出\(n,s_{1,2,...,n}\),定义一个五元组\((a,b,c,d,e)\)合法当且仅当: \[1\le a,b,c,d,e\le n \] \[(s_a\vee s ...

  8. CF914G Sum the Fibonacci FWT、子集卷积

    传送门 一道良心的练习FWT和子集卷积的板子-- 具体来说就是先把所有满足\(s_a \& s_b = 0\)的\(s_a \mid s_b\)的值用子集卷积算出来,将所有\(s_a \opl ...

  9. CF914G Sum the Fibonacci

    解:发现我们对a和b做一个集合卷积,对d和e做一个^FWT,然后把这三个全部对位乘上斐波那契数,然后做&FWT就行了. #include <bits/stdc++.h> , MO ...

随机推荐

  1. iOS中获取系统相册中的图片

    一.获取单张图片 思路: 1.利用UIImagePickerController可以从系统自带的App(照片\相机)中获得图片 2.设置代理,遵守代理协议 注意这个UIImagePickerContr ...

  2. android webview 加载本地html 实现 与 java 之间的相互响应

    1.布局 <?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:androi ...

  3. eclipse 给jar包关联javadoc

    1.右键点击Referenced Libraries下的jar --> 选择 Build Path --> Configure Build Path. 2.选择jar的Javadoc lo ...

  4. CSS中设置div垂直居中

    在说到这个问题的时候,也许有人会问CSS中不是有vertical-align属性来设置垂直居中的吗?即使是某些浏览器不支持我只需做少许的CSS Hack技术就可以啊!所以在这里我还要啰嗦两句,CSS中 ...

  5. Lorenzo Von Matterhorn(STL_map的应用)

    Lorenzo Von Matterhorn time limit per test 1 second memory limit per test 256 megabytes input standa ...

  6. 九度OJ 1261:寻找峰值点 (基础题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:500 解决:37 题目描述: 给定一个整数序列,该整数序列存在着这几种可能:先递增后递减.先递减后递增.全递减.全递增. 请找出那个最大值的 ...

  7. 从分布式锁来看redis和zookpeer!

    从分布式锁来看redis和zookpeer! 目前网上大部分的基于zookpeer,和redis的分布式锁的文章都不够全面.要么就是特意避开集群的情况,要么就是考虑不全,读者看着还是一脸迷茫.坦白说, ...

  8. linux 11 -- mount,umount

    Linux 文件系统是一个以 / 为根的大树,我们在不同的设备和分区上都有文件系统.我们如何处理这种明显的不一致性?根 (/) 文件系统是在初始化过程中挂载的.您创建的其他每个文件系统在挂载 在挂载点 ...

  9. 每天一个Linux命令(18)loacte命令

    locate 让使用者可以很快速的搜寻档案系统内是否有指定的档案.     (1)用法:   用法:  Locate  [选项] [参数]     (2)功能: 功能:  在mlocate数据库中搜索 ...

  10. 【leetcode刷题笔记】Substring with Concatenation of All Words

    You are given a string, S, and a list of words, L, that are all of the same length. Find all startin ...