题目描述

给出一个长度为 $n$ 的序列 $\{s\}$ ,对于所有满足以下条件的五元组 $(a,b,c,d,e)$ :

  • $1\le a,b,c,d,e\le n$ ;
  • $(s_a|s_b)\&s_c\&(s_d\text{^}s_e)=2^i$ ,其中 $i$ 为非负整数 ;
  • $s_a\&s_b=0$ 。

求 $f(s_a|s_b)\times f(s_c)\times f(s_d\text{^}s_e)$ 的和模 $10^9+7$,其中 $f(i)$ 表示斐波那契数列的第 $i$ 项( $f(0)=0,f(1)=1$ )。


题解

FWT+FST(Fast-Subset-Transform)

显然是求 $cnt[s_a]$ 和 $cnt[s_b]$ 的子集卷积得出 $cnt[s_a|s_b]$ ,求 $cnt[s_d]$ 和 $cnt[s_e]$ 的异或卷积得出 $cnt[s_d\text{^}s_e]$ ,然后求 $cnt[s_a|s_b]\times f[s_a|s_b]$ 、$cnt[s_c]\times f[s_c]$ 、$cnt[s_d\text{^}s_e]\times f[s_d\text{^}s_e]$ 的与卷积,与卷积的 $2^i$ 项之和即为答案。

(子集卷积:$c$ 是 $a$ 和 $b$ 的子集卷积,当且仅当:$c[i]=\sum\limits_{j|k=i,j\&k=0}a[j]\times b[k]$ ,直观理解上等价于 $c[i]=\sum\limits_{j\in i}a[j]\times b[i-j]$ ,故称子集卷积)

异或卷积和与卷积可以直接使用FWT计算。

子集卷积的计算方法可以参考vfk集训队论文中提到的占位多项式法:

$j|k=i,j\&k=0$ 等价于 $j|k=i,|j|+|k|=|i|$ 。

因此求 $c'[p][i]=\sum\limits_{j|k=i,|j|+|k|=p}a[j]\times b[k]=\sum\limits_{j|k=i,|j|+|k|=p}a'[|j|][j]\times b'[|k|][k]=\sum\limits_{j|k=i,q+r=p}a'[q][j]+b'[r][k]$ ,那么 $c[i]=c'[|i|][i]$ 。

其中 $|i|$ 表示 $i$ 集合的大小,即 $i$ 二进制中 $1$ 的个数。$a'[|i|][i]=a[i]$ ,其余为0;$b'$ 同理。

那么我们对每一个 $a'[q][]$ 和 $b'[r][]$ 分别求DWT,然后进行类似背包合并的卷积,再求IDWT即可。这个部分的时间复杂度为 $O(2^{17}·17^2)$ 。

因此总的时间复杂度为 $O(2^{17}·17^2+2^{17}·17·常数)$ 。

这里我脑残了... $cnt[s_a,s_b,s_c,s_d,s_e]$ 都是一样的,因此可以减少DWT的次数... 不管了反正A了...

#include <cstdio>
#include <algorithm>
#define N 131100
#define mod 1000000007
#define inv 500000004
using namespace std;
typedef long long ll;
int s[1000010] , cnt[N];
ll fib[N] , a[18][N] , b[18][N] , c[N] , d[N] , e[N] , f[18][N];
int main()
{
int n , m = 1 , mx = 0 , k , i , j;
ll t , ans = 0;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &s[i]) , mx = max(mx , s[i]);
while(m <= mx) m <<= 1;
fib[1] = 1;
for(i = 2 ; i < m ; i ++ ) fib[i] = (fib[i - 1] + fib[i - 2]) % mod;
for(i = 1 ; i < m ; i ++ ) cnt[i] = cnt[i - (i & -i)] + 1;
for(i = 1 ; i <= n ; i ++ ) a[cnt[s[i]]][s[i]] ++ , b[cnt[s[i]]][s[i]] ++ , c[s[i]] ++ , d[s[i]] ++ , e[s[i]] ++ ;
for(i = 0 ; i < m ; i ++ ) c[i] = c[i] * fib[i] % mod;
for(i = 1 ; i < m ; i <<= 1) for(j = 0 ; j < m ; j ++ ) if(i & j) t = d[j] , d[j] = (d[j - i] - t + mod) % mod , d[j - i] = (d[j - i] + t) % mod;
for(i = 1 ; i < m ; i <<= 1) for(j = 0 ; j < m ; j ++ ) if(i & j) t = e[j] , e[j] = (e[j - i] - t + mod) % mod , e[j - i] = (e[j - i] + t) % mod;
for(i = 0 ; i < m ; i ++ ) d[i] = d[i] * e[i] % mod;
for(i = 1 ; i < m ; i <<= 1) for(j = 0 ; j < m ; j ++ ) if(i & j) t = d[j] , d[j] = (d[j - i] - t + mod) * inv % mod , d[j - i] = (d[j - i] + t) * inv % mod;
for(i = 0 ; i < m ; i ++ ) d[i] = d[i] * fib[i] % mod;
for(k = 0 ; k <= cnt[m - 1] ; k ++ )
{
for(i = 1 ; i < m ; i <<= 1) for(j = 0 ; j < m ; j ++ ) if(i & j) a[k][j] = (a[k][j] + a[k][j - i]) % mod;
for(i = 1 ; i < m ; i <<= 1) for(j = 0 ; j < m ; j ++ ) if(i & j) b[k][j] = (b[k][j] + b[k][j - i]) % mod;
}
for(i = 0 ; i <= cnt[m - 1] ; i ++ )
for(j = 0 ; j <= cnt[m - 1] - i ; j ++ )
for(k = 0 ; k < m ; k ++ )
f[i + j][k] = (f[i + j][k] + a[i][k] * b[j][k]) % mod;
for(k = 0 ; k <= cnt[m - 1] ; k ++ ) for(i = 1 ; i < m ; i <<= 1) for(j = 0 ; j < m ; j ++ ) if(i & j) f[k][j] = (f[k][j] - f[k][j - i] + mod) % mod;
for(i = 0 ; i < m ; i ++ ) e[i] = f[cnt[i]][i] * fib[i] % mod;
for(i = 1 ; i < m ; i <<= 1) for(j = 0 ; j < m ; j ++ ) if(i & j) c[j - i] = (c[j - i] + c[j]) % mod;
for(i = 1 ; i < m ; i <<= 1) for(j = 0 ; j < m ; j ++ ) if(i & j) d[j - i] = (d[j - i] + d[j]) % mod;
for(i = 1 ; i < m ; i <<= 1) for(j = 0 ; j < m ; j ++ ) if(i & j) e[j - i] = (e[j - i] + e[j]) % mod;
for(i = 0 ; i < m ; i ++ ) c[i] = c[i] * d[i] % mod * e[i] % mod;
for(i = 1 ; i < m ; i <<= 1) for(j = 0 ; j < m ; j ++ ) if(i & j) c[j - i] = (c[j - i] - c[j] + mod) % mod;
for(i = 1 ; i < m ; i <<= 1) ans = (ans + c[i]) % mod;
printf("%lld\n" , ans);
return 0;
}

【codeforces914G】Sum the Fibonacci FWT+FST(快速子集变换)的更多相关文章

  1. 知识点简单总结——FWT(快速沃尔什变换),FST(快速子集变换)

    知识点简单总结--FWT(快速沃尔什变换),FST(快速子集变换) 闲话 博客园的markdown也太傻逼了吧. 快速沃尔什变换 位运算卷积 形如 $ f[ i ] = \sum\limits_{ j ...

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

  3. 快速沃尔什变换(FWT) 与 快速莫比乌斯变换 与 快速沃尔什变换公式推导

    后面的图片将会告诉: 如何推出FWT的公式tf 如何推出FWT的逆公式utf 用的是设系数,求系数的方法! ============================================== ...

  4. 快速沃尔什变换(FWT)及K进制异或卷积&快速子集变换(FST)讲解

    前言: $FWT$是用来处理位运算(异或.与.或)卷积的一种变换.位运算卷积是什么?形如$f[i]=\sum\limits_{j\oplus k==i}^{ }g[j]*h[k]$的卷积形式(其中$\ ...

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

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

  6. Codeforces914G Sum the Fibonacci(FWT)

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

  7. FWT,FST入门

    0.目录 目录 0.目录 1.什么是 FWT 2. FWT 怎么做 2.1. 或卷积 2.2.与卷积 2.3.异或卷积 2.4.例题 3. FST 3.1. FST 怎么做 3.2.例题 1.什么是 ...

  8. CF914G Sum the Fibonacci(FWT,FST)

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

  9. 【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 ...

随机推荐

  1. 【Todo】找出共同好友 & Spark & Hadoop面试题

    找了这篇文章看了一下面试题<Spark 和hadoop的一些面试题(准备)> http://blog.csdn.net/qiezikuaichuan/article/details/515 ...

  2. RHCE-EXAM 模拟题目

    真实考试环境说明: 你考试所用的真实物理机器会使用普通账号自动登陆,登陆后,桌面会有两个虚拟主机图标,分别是system1和system2.所有的考试操作都是在system1和system2上完成.S ...

  3. mongdb基础

    查看数据库 show dbs; 切换到需要使用的数据库:use local; 显示集合中的数据库表:show collections; 切换到数据库test,如果数据库不存在,则自动创建 插入数据 d ...

  4. 解决Extjs有IE下z-index属性的问题

    在用Extjs时,有时候,在Google浏览器上面没有任何问题,但是相同的页面在IE下面就会有问题,直接报错,点击中断,进行后可以看到如下的信息: Google里面没这个问题,加一句代码就能解决在窗体 ...

  5. 第六章P2P技术及应用

    第六章P2P技术及应用 P2P技术在我们日常生活中非常实用,例如我们常用的QQ.PPLive.BitTorrent就是基于P2P技术研发.下面将本章中的重点内容进行归纳. 文章中的Why表示产生的背景 ...

  6. CentOS 7.2二进制安装mysql-5.7.19

    官方文档地址:https://dev.mysql.com/doc/refman/5.7/en/binary-installation.html 开始安装 1.下载mysql二进制包 # cd /usr ...

  7. KRKR基础篇(二)

    这里介绍一些krkr的语法规范,具体的命令含义及用法以后再叙述 一:kag语法及基本概念 KAG使用的剧本语言为KAG Script,文件扩展名为.ks 脚本内的文字除  注释,  命令 ,  段落标 ...

  8. jquery on函数和prop与attr区别

    一.jquery on()方法 1.语法 2.例子 $(document).ready(function(){ $("p").on("click",functi ...

  9. [linux] centos搭建openvpn服务,脚本颁发/吊销证书 (转载+原创)

    搭建过程转载:http://yestreenstars.blog.51cto.com/1836303/1429537 环境说明:服务端:CentOS 6.5_X64客户端:Windows 7 服务端配 ...

  10. ES6的新特性(15)——Promise 对象

    Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大.它由社区最早提出和实现,ES6 将其写进了语言标准,统一了 ...