博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
codeforces914G Sum the Fibonacci
阅读量:4554 次
发布时间:2019-06-08

本文共 2154 字,大约阅读时间需要 7 分钟。

题目大意:给定一个长为$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取模。

 

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

 

看到这道题,看到应该想到对于一个五元组$(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
#include
#include
#include
#include
#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 3llusing 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
<<=1){ for(LL st=0;st
<<1)){ for(LL pos=st;pos
a1,a2,a3 into --> sumof(1) sumof(2)... at t[] for(len=1;len<=maxn;len<<=1) top++; for(LL i=0;i
ans --> UFWT ans for(LL i=1ll;i
<<=1) tt=add(tt,ans[i]); write(tt); //print answer return 0;}

转载于:https://www.cnblogs.com/OYJason/p/9362570.html

你可能感兴趣的文章
JPA + SpringData 操作数据库原来可以这么简单 ---- 深入了解 JPA - 2
查看>>
使用 Hadoop 进行语料处理(面试题)
查看>>
webmagic学习之路-1:采集安居客列表页测试
查看>>
node的consoidate的插件统一
查看>>
POj2387——Til the Cows Come Home——————【最短路】
查看>>
EPLAN标题页及图框的设计
查看>>
坐标下降法(coordinate descent method)求解LASSO的推导
查看>>
读后疑问
查看>>
实力为王 八年DBA经验谈
查看>>
More Effective C++ (静态绑定与动态类型)
查看>>
shell脚本57问
查看>>
2-sat 问题 【例题 Flags(2-sat+线段树优化建图)】
查看>>
ext3.2 右击动态添加node的treepanel
查看>>
Database links
查看>>
GitHub 优秀的 Android 开源项目
查看>>
uva10158
查看>>
深入浅出Mybatis-与Spring集成
查看>>
跨域访问-需要设置HTTP响应标头
查看>>
1035 插入与归并(25 分)
查看>>
STL中排序函数的用法(Qsort,Sort,Stable_sort,Partial_sort,List::sort)
查看>>