题目: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. c++第二十三天

    p124~p126: 算数运算符 1.形如+ -(一元) * / % + -(二元)为算数运算符. 2.所有算数运算符都满足左结合律. 3.算数运算符的运算对象和求值结果都是右值. 4.在表达式求值之 ...

  2. c++语言中的遍历

    原文地址:http://www.cnblogs.com/xylc/p/3653036.html 随着C++11标准的出现,C++标准添加了许多有用的特性,C++代码的写法也有比较多的变化. vecto ...

  3. 2017-2018-1 JaWorld 第四、五周作业

    2017-2018-1 JaWorld 第四.五周作业 两周工作内容 小组讨论并确定最终的app雏形 合作完成需求说明书 工作分工 成员 分工 比例 陈是奇 1.引言 8% 马平川 2.1-2.5 产 ...

  4. 数据库常见的三种join方式

    数据库常见的join方式有三种:inner join, left outter join, right outter join(还有一种full join,因不常用,本文不讨论).这三种连接方式都是将 ...

  5. 解决 vim 乱码

    打开vim安装目录下的_vimrc,在头部加上几句配置语句就能搞定: //设置默认编码 set encoding=utf-8 set fileencodings=utf-8,chinese,latin ...

  6. python 操作Excel表格,解压zip包,压缩zip包,目录遍历

    import zipfile import os,shutil import openpyxl file_list_pos="" fileName="" zip ...

  7. tp5集成淘宝,微信,网易,新浪等第三方登录

    tp5集成淘宝,微信,网易,新浪等第三方登录 一.总结 一句话总结: 接口 链接 实现的话就是这些平台给的一个接口(链接),你通过这些接口登录进去之后,它会给你返回用户名,头像之类的信息,我们的网站存 ...

  8. js比较时间大小(时间为以-分割的字符串时)

    function dateCompare(startdate, enddate) {    var arr = startdate.split("-");    var start ...

  9. Learn Rails5.2- ActiveRecord: sqlite3的用法, Query查询语法。乐观锁和悲观锁案例,查询语法includes(), 多态关联,destory和delete, Scope, Validats, Migrations

    rails generate model photo title:string album:references 这会产生一个album_id列,当建立belongs_to关联时,需要用到. refe ...

  10. Spring4 MVC HelloWorld 注解和JavaConfig实例

    在这一节中,我们以 Spring4 MVC HelloWorld 注释/JavaConfig为示例,一步一步以简单的方式学习Spring4 MVC 的注解,项目设置,代码,部署和运行. 在先前的 Sp ...