题目描述

给出一个长度为 $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. 学号 2016-2017-20155329《Java程序设计》课程总结

    学号 2016-2017-20155329<Java程序设计>课程总结 (按顺序)每周作业链接汇总 预备作业1:想象中的师生关系 预备作业2:C语言水平调查以及认为自己最强的一项技能和毕业 ...

  2. 【LG3723】[AHOI2017/HNOI2017]礼物

    [LG3723][AHOI2017/HNOI2017]礼物 题面 洛谷 题解 首先我们将\(c\)看作一个可以为负的整数,那么我们就可以省去讨论在哪个手环加\(c\)的繁琐步骤了 设我们当前已经选好了 ...

  3. python爬虫入门之URL

    python爬虫,顾名思义是爬取信息的.大数据时代,信息的获取是非常关键的,它甚至能决定一个公司大发展的方向与未来,互联网就好像一张大网,人们想要获取信息就要从这张大网里爬取,这种手段也可以称为搜索引 ...

  4. AndroidStudio 新建不同的Drawable文件夹

    以前习惯eclipse开发Android的朋友们知道 新创建一个Android项目的时候eclipse会自动生成多个drawable文件夹来存放图片 但是Android Studio 新建项目的时候只 ...

  5. MySQL数据库--连接

    MySQL数据库的概念: MySQL数据库,包括客户端和服务端.客户端就是操作数据库的终端(命令行.navicat),服务端就是安装有MySQL软件的主机(本机或者服务器),MySQL数据库的端口一般 ...

  6. 【洛谷】题解 P1056 【排座椅】

    题目链接 因为题目说输入保证会交头接耳的同学前后相邻或者左右相邻,所以一对同学要分开有且只有一条唯一的通道才能把他们分开. 于是可以吧这条通道累加到一个数组里面.应为题目要求纵列的通道和横列的通道条数 ...

  7. HDU-4055:Number String

    链接:HDU-4055:Number String 题意:给你一个字符串s,s[i] = 'D'表示排列中a[i] > a[i+1],s[i] = 'I'表示排列中a[i] < a[i+1 ...

  8. 袋鼠云研发手记 | 数栈·开源:Github上400+Star的硬核分布式同步工具FlinkX

    作为一家创新驱动的科技公司,袋鼠云每年研发投入达数千万,公司80%员工都是技术人员,袋鼠云产品家族包括企业级一站式数据中台PaaS数栈.交互式数据可视化大屏开发平台Easy[V]等产品也在迅速迭代.在 ...

  9. python怎么安装requests、beautifulsoup4等第三方库

    零基础学习python最大的难题之一就是安装所有需要的软件,下面来简单介绍一下如何安装用pip安装requests.beautifulsoup4等第三方库:   方法/步骤     点击开始,在运行里 ...

  10. tikv 安装

    export HostIP="127.0.0.1" docker run -d -p 2379:2379 -p 2380:2380 --name pd pingcap/pd \ - ...