codeforces914G Sum the Fibonacci

题目大意:给定一个长为$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的更多相关文章
- Codeforces914G Sum the Fibonacci(FWT)
FWT大杂烩.跟着模拟做很多次FWT即可. #include<iostream> #include<cstdio> #include<cmath> #include ...
- 【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 ...
- CF914G Sum the Fibonacci(FWT,FST)
CF914G Sum the Fibonacci(FWT,FST) Luogu 题解时间 一堆FWT和FST缝合而来的丑陋产物. 对 $ cnt[s_{a}] $ 和 $ cnt[s_{b}] $ 求 ...
- 【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)\& ...
- 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 | ...
- CF 914 G Sum the Fibonacci —— 子集卷积,FWT
题目:http://codeforces.com/contest/914/problem/G 其实就是把各种都用子集卷积和FWT卷起来算即可: 注意乘 Fibonacci 数组的位置: 子集卷积时不能 ...
- 题解 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 ...
- CF914G Sum the Fibonacci FWT、子集卷积
传送门 一道良心的练习FWT和子集卷积的板子-- 具体来说就是先把所有满足\(s_a \& s_b = 0\)的\(s_a \mid s_b\)的值用子集卷积算出来,将所有\(s_a \opl ...
- CF914G Sum the Fibonacci
解:发现我们对a和b做一个集合卷积,对d和e做一个^FWT,然后把这三个全部对位乘上斐波那契数,然后做&FWT就行了. #include <bits/stdc++.h> , MO ...
随机推荐
- iOS 递归锁
原理:递归锁也是通过 pthread_mutex_lock 函数来实现,在函数内部会判断锁的类型.NSRecursiveLock 与 NSLock 的区别在于内部封装的 pthread_mutex_t ...
- hdu 4902 Nice boat(线段树区间改动,输出终于序列)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 Problem Description There is an old country and ...
- 【智力题】IO——行测、笔试、面试中遇到的
昨天(05.23)下午去参加了明源软件的暑期实习宣讲+笔试,第一次听说这个行业,行业和笔试风格完全不一样啊,5道行测智力题+1个问答+ 斐波那契数列 + 洗牌算法(思想.流程图.代码),今年回来后线上 ...
- Spring 和 filter
标题是 spring和filter,但是这里却是说的spring MVC 项目中需要用到filter,filter中需要用到spring实例化的bean,于是为了简化就形成spring和filter了 ...
- Python高级入门01-property
JAVA中存在对变量 私有化,公开,保护... 私有化时候,需要提供一个公开的get 和 set方法对外公开,让别人进行调用 python中同样存在 私有化变量定义是__是这个双下划线,eg:_ ...
- 使用weka训练一个分类器
1 训练集数据 1.1 csv格式 5.1,3.5,1.4,0.2,Iris-setosa 4.9,3.0,1.4,0.2,Iris-setosa 4.7,3.2,1.3,0.2,Iris-setos ...
- mysql导出数据或结构
导出整个数据库结构和数据 $ mysqldump -h localhost -uroot -p123456 database > dump.sql 导出单个数据表结构和数据 $ mysqldum ...
- 2017-2018-1 20179209《Linux内核原理与分析》第十周作业
设备与模块 设备分类 块设备 块设备可以以块为单位寻址,块大小随设备不同而不同:设备通常支持重定位操作,也就是对数据的随机访问.块设备的例子有外存,光盘等. 字符设备 字符设备不可寻址,仅供数据的流式 ...
- Javaweb基础--->监听器listener(转发)
JavaWeb中的监听器 1.基本概念 JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext, HttpSession和 Servl ...
- QT5的QDesktopSerivices不同
QT4使用QDesktopServices::storageLocation(QDesktopServices::xxxx)来获取一些系统目录, 现在则要改成QStandardPaths::writa ...