题目:http://codeforces.com/contest/914/problem/G

第一个括号可以子集卷积;第三个括号可以用 FWT 异或卷积;这样算出选两个数组成 x 的方案数;三个部分的方案数分别乘上 f[ x ] 再一起与卷积即可。

注意子集卷积的时候不要改 tp[ i ][ s ] ,因为要的是恰好两个数拼起来,没有改过的(但是做过 FMT 的) tp[ i ][ s ] 存的是初值,表示选 1 个数的方案数。

  所以如果可以选任意多个数,就可以像背包一样, tp[ j ][ s ] 用的改过的, tp[ i-j ][ s ] 用没改过的。

累计完 tp[ i ][ s ] 的时候,要在 i 这一层 iFMT 回去,再贡献给 a[ s ] ,不要直接加到 a[ s ] 上、做完所有的 i 之后再 iFMT 回去,因为 iFMT 只能弄回去对于同一个 i 的。

卷积的时候不要对 i - j == j 的情况去重,因为可以选重复的。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mx(int a,int b){return a>b?a:b;}
const int K=,N=(<<K)+,mod=1e9+;
int f[N],a[N],b[N],c[N],bin[K+],len,bh;
int ct[N],tp[K+][N];
void upd(int &x){x>=mod?x-=mod:;}
void init()
{
bin[]=;for(int i=;i<=K;i++)bin[i]=bin[i-]<<;
for(int s=,j=bin[K];s<j;s++)ct[s]=ct[s-(s&-s)]+;
f[]=;f[]=;for(int i=,j=bin[K];i<j;i++)f[i]=f[i-]+f[i-],upd(f[i]);
}
void fwt_and(int *a,bool fx)
{
for(int R=;R<=len;R<<=)
for(int i=,m=R>>;i<len;i+=R)
for(int j=;j<m;j++)
a[i+j]+=(fx?mod-a[i+m+j]:a[i+m+j]),upd(a[i+j]);
}
void dv2(int &x){if(x&)x=(x+mod)>>; else x>>=;}
void fwt_xor(int *a,bool fx)
{
for(int R=;R<=len;R<<=)
for(int i=,m=R>>;i<len;i+=R)
for(int j=;j<m;j++)
{
int x=a[i+j],y=a[i+m+j];
a[i+j]=x+y; a[i+m+j]=x+mod-y;
upd(a[i+j]); upd(a[i+m+j]);
if(fx)dv2(a[i+j]),dv2(a[i+m+j]);
}
}
void fmt(int *a,bool fx)
{
for(int i=;i<len;i<<=)
for(int s=;s<len;s++)
if(s&i)a[s]+=(fx?mod-a[s^i]:a[s^i]),upd(a[s]);
}
void cz()
{
int t[N];
for(int i=;i<=bh;i++)fmt(tp[i],);//<= not <
for(int i=;i<=bh;i++)
{
for(int s=;s<len;s++)t[s]=;
for(int j=;j<=i;j++)
for(int s=;s<len;s++)
t[s]=(t[s]+(ll)tp[j][s]*tp[i-j][s])%mod;
fmt(t,);
for(int s=;s<len;s++)
if(i==ct[s])a[s]+=t[s],upd(a[s]);
}
/*
for(int i=0;i<=bh;i++)
{
for(int j=0;j<=i;j++)
for(int s=0;s<len;s++)
{
if(i!=ct[s])continue;//
a[s]=(a[s]+(ll)tp[j][s]*tp[i-j][s])%mod;//i-j==j is ok!
}
}
fmt(a,1);
*/
}
int main()
{
init();int n=rdn(),mx=;
for(int i=,d;i<=n;i++)
{
d=rdn();mx=Mx(mx,d);
tp[ct[d]][d]++;c[d]++;b[d]+=f[d];upd(b[d]);
}
for(bh=;bin[bh]<=mx;bh++);len=bin[bh];
cz();
fwt_xor(c,);for(int i=;i<len;i++)c[i]=(ll)c[i]*c[i]%mod;fwt_xor(c,);
for(int i=;i<len;i++)a[i]=(ll)a[i]*f[i]%mod;
for(int i=;i<len;i++)c[i]=(ll)c[i]*f[i]%mod;
fwt_and(a,); fwt_and(b,); fwt_and(c,);
for(int i=;i<len;i++)a[i]=(ll)a[i]*b[i]%mod*c[i]%mod;
fwt_and(a,);
int ans=;
for(int i=;i<len;i<<=)ans+=a[i],upd(ans);
printf("%d\n",ans);
return ;
}

CF 914G Sum the Fibonacci——子集卷积的更多相关文章

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

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

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

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

  3. CF914G Sum the Fibonacci (快速沃尔什变换FWT + 子集卷积)

    题面 题解 这是一道FWT和子集卷积的应用题. 我们先设 cnt[x] 表示 Si = x 的 i 的数量,那么 这里的Nab[x]指满足条件的 Sa|Sb=x.Sa&Sb=0 的(a,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. 【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 ...

  6. 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 | ...

  7. UOJ 348 【WC2018】州区划分——子集卷积

    题目:http://uoj.ac/problem/348 参考:https://www.cnblogs.com/NaVi-Awson/p/9242645.html#%E5%AD%90%E9%9B%86 ...

  8. UOJ #348 州区划分 —— 状压DP+子集卷积

    题目:http://uoj.ac/problem/348 一开始可以 3^n 子集DP,枚举一种状态的最后一个集合是什么来转移: 设 \( f[s] \) 表示 \( s \) 集合内的点都划分好了, ...

  9. UOJ348 WC2018 州区划分 状压DP、欧拉回路、子集卷积

    传送门 应该都会判欧拉回路吧(雾 考虑状压DP:设\(W_i\)表示集合\(i\)的点的权值和,\(route_i\)表示点集\(i\)的导出子图中是否存在欧拉回路,\(f_i\)表示前若干个城市包含 ...

随机推荐

  1. pyimage search研究

    包括<软实力>的作者,类似 http://www.learnopencv.com/, 这次调查研究的 http://www.pyimagesearch.com 是一个独立的博客,作者是机器 ...

  2. 20145118 《Java程序设计》第5周学习总结 教材学习内容总结

    20145118 <Java程序设计>第5周学习总结 教材学习内容总结 1.Java中所有错误都会被打包成对象,可以通过try.catch语法对错误对象作处理,先执行try,如果出错则跳出 ...

  3. Java实现:数据结构之排序

    Java实现:数据结构之排序 0.概述 形式化定义:假设有n个记录的序列(待排序列)为{ R1, R2 , -, Rn },其相应的关键字序列为 { K1, K2, -, Kn }.找到{1,2, - ...

  4. FromBottomToTop第十三周项目博客

    FromBottomToTop第十三周项目博客 本周项目计划 完成游戏核心算法以及界面相关类和怪物类 项目进展 用户可选择游戏模式,共有20张不同的地图. 炮台的建立和升级. 小怪的路径算法. 参考资 ...

  5. 《Effective Java 2nd》第8章 通用程序设计

    目录 第45条 将局部变量的作用域最小化 第46条 for-each循环优先于传统的for循环 第47条 了解和使用类库 第48条 如果需要精确的答案,避免使用float和double 第49条 基本 ...

  6. HYSBZ 1036 树的统计Count(树链剖分)题解

    思路: 树链剖分,不知道说什么...我连模板都不会用 代码: #include<map> #include<ctime> #include<cmath> #incl ...

  7. 枚举子集&高位前缀和

    最近做的题里面有这个东西,于是写一篇博客总结一下吧. 枚举子集 枚举子集就是状压的时候枚举其中的二进制位中的1的子集.直接暴力枚举二进制位时间复杂度是\(O(4^n)\),但是我们可以发现,对于每一位 ...

  8. Redis之字符串

    Redis 字符串 String 是redis最基本的类型,value 不仅可以是 String,也可以是数字. 使用 Strings 类型,可以完全实现目前 Memcached 的功能,并且效率更高 ...

  9. 一次完整的HTTP事务是怎样一个过程

    当我们在浏览器的地址栏输入 www.linux178.com,然后回车,回车这一瞬间到看到页面到底发生了什么呢? 以下过程仅是个人理解: 域名解析 --> 发起TCP的3次握手 --> 建 ...

  10. CSS之旋转立方体

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...