题目传送门

题目大意

给出\(n,s_{1,2,...,n}\),定义一个五元组\((a,b,c,d,e)\)合法当且仅当:

  1. \[1\le a,b,c,d,e\le n
    \]
  2. \[(s_a\vee s_b)\wedge s_c \wedge (s_d\oplus s_e)=2^i,i\in \mathbb{Z}
    \]
  3. \[s_a\wedge s_b=0
    \]

求出对于所有合法的五元组\((a,b,c,d,e)\):

\[\sum f(s_a\vee s_b)f(s_c)f(s_d\oplus s_e)
\]

其中\(f(i)\)表示第\(i\)位斐波拉契数列。

思路

其实这个题应该算\(\text {FST}\)的入门级题目,也不是很难。

首先,我们定义\(v(a,b,c,d,e)=(s_a\vee s_b)\wedge s_c \wedge (s_d\oplus s_e)\)。于是我们可以把式子写成这样一个形式:

\[\sum_{i} \sum_{v(a,b,c,d,e)=2^i} [s_a\wedge s_b=0]f(s_a\vee s_b)f(s_c)f(s_d\oplus s_e)
\]
\[=\sum_{p} \sum_{i\wedge j\wedge k=2^p} f(i)f(j)f(k)(\sum_{s_a\vee s_b=i,s_a\wedge s_b=0}1)(\sum_{s_a\oplus s_b=k}1)
\]

然后我们就发现第一个括号里面的可以用子集卷积求到,后面那个可以用异或卷积求到,总的又可以用并卷积求到。于是我们就可以在\(\Theta(w\log ^2w)\)的时间内求到了。其中\(w\)是值域。

\(\text {Code}\)

#include <bits/stdc++.h>
using namespace std; #define Int register int
#define inv2 500000004
#define mod 1000000007
#define MAXN 1000005 template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');} int lim = 1; void mul (int &a,int b){a = 1ll * a * b % mod;}
void del (int &a,int b){a = a >= b ? a - b : a + mod - b;}
void add (int &a,int b){a = a + b >= mod ? a + b - mod : a + b;} void ORFWT (int *A,int type){
for (Int i = 1;i < lim;i <<= 1)
for (Int j = 0;j < lim;j += i << 1)
for (Int k = 0;k < i;++ k)
if (type == 1) add (A[i + j + k],A[j + k]);
else del (A[i + j + k],A[j + k]);
} void ANDFWT (int *A,int type){
for (Int i = 1;i < lim;i <<= 1)
for (Int j = 0;j < lim;j += i << 1)
for (Int k = 0;k < i;++ k)
if (type == 1) add (A[j + k],A[i + j + k]);
else del (A[j + k],A[i + j + k]);
} void XORFWT (int *A,int type){
for (Int i = 1;i < lim;i <<= 1)
for (Int j = 0;j < lim;j += i << 1)
for (Int k = 0;k < i;++ k){
int x = A[j + k],y = A[i + j + k];
if (type == 1) A[j + k] = (x + y) % mod,A[i + j + k] = (x + mod - y) % mod;
else A[j + k] = 1ll * (x + y) * inv2 % mod,A[i + j + k] = 1ll * (x + mod - y) * inv2 % mod;
}
} int n,s,fib[1 << 17],cnt[1 << 17],A[1 << 17],S[1 << 17],f[18][1 << 17],h[1 << 17],sum[1 << 17]; signed main(){
read (n);
fib[0] = 0,fib[1] = cnt[1] = 1;int maxn = 0;
for (Int i = 2;i < (1 << 17);++ i) fib[i] = (fib[i - 1] + fib[i - 2]) % mod,cnt[i] = cnt[i >> 1] + (i & 1);
for (Int i = 1,s;i <= n;++ i) read (s),maxn = max (maxn,s),add (f[cnt[s]][s],1),add (h[s],1),add (sum[s],fib[s]);
int logn = 0;while (lim <= maxn) lim <<= 1,logn ++;
for (Int i = 0;i <= logn;++ i) ORFWT (f[i],1);
for (Int i = 0;i <= logn;++ i){
for (Int j = 0;j < lim;++ j) S[j] = 0;
for (Int j = 0;j <= i;++ j)
for (Int k = 0;k < lim;++ k)
add (S[k],1ll * f[j][k] * f[i - j][k] % mod);
ORFWT (S,-1);
for (Int j = 0;j < lim;++ j) if (cnt[j] == i) add (A[j],S[j]);
}
XORFWT (h,1);
for (Int i = 0;i < lim;++ i) mul (h[i],h[i]);
XORFWT (h,-1);
for (Int i = 0;i < lim;++ i) mul (A[i],fib[i]),mul (h[i],fib[i]);
ANDFWT (A,1),ANDFWT (h,1),ANDFWT (sum,1);
for (Int i = 0;i < lim;++ i) mul (A[i],h[i]),mul (A[i],sum[i]);
ANDFWT (A,-1);
int ans = 0;for (Int i = 1;i < lim;i <<= 1) add (ans,A[i]);
write (ans),putchar ('\n');
return 0;
}

题解 CF914G Sum the Fibonacci的更多相关文章

  1. CF914G Sum the Fibonacci(FWT,FST)

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

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

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

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

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

  4. CF914G Sum the Fibonacci

    解:发现我们对a和b做一个集合卷积,对d和e做一个^FWT,然后把这三个全部对位乘上斐波那契数,然后做&FWT就行了. #include <bits/stdc++.h> , MO ...

  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. 【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)\& ...

  8. LeetCode题解——Two Sum

    题目地址:https://oj.leetcode.com/problems/two-sum/ Two Sum Given an array of integers, find two numbers ...

  9. LeetCode题解之Sum Root to Leaf Numbers

    1.题目描述 2.问题分析 记录所有路径上的值,然后转换为int求和. 3.代码 vector<string> s; int sumNumbers(TreeNode* root) { tr ...

随机推荐

  1. openstack新建实例各种报错解决

    最近自己装了下Openstack,零基础安装,参照了网上不少教程. 吃了百家饭的后果,就是出现了一堆不明问题...openstack安装比较复杂,很多配置文件,一个地方配置不正确,可能会导致后面的功能 ...

  2. Mysql You can't specify target table 'newsalrecord' for update in FROM clause

    这个问题是不能先select出同一表中的某些值,再update这个表(在同一语句中),即不能依据某字段值做判断再来更新某字段的值.解决办法就是建立个临时的表.

  3. MySQL案例:一次单核CPU占用过高问题的处理

    客户现场反馈,top的检查结果中,一个CPU的占用一直是100%.实际上现场有4个CPU,而且这个服务器是mysql专属服务器. 我的第一反应是io_thread一类的参数设置有问题,检查以后发现re ...

  4. 《手把手教你》系列技巧篇(二十三)-java+ selenium自动化测试-webdriver处理浏览器多窗口切换下卷(详细教程)

    1.简介 上一篇讲解和分享了如何获取浏览器窗口的句柄,那么今天这一篇就是讲解获取后我们要做什么,就是利用获取的句柄进行浏览器窗口的切换来分别定位不同页面中的元素进行操作. 2.为什么要切换窗口? Se ...

  5. 174道 JavaScript 面试题,助你查漏补缺

    最近在整理 JavaScript 的时候发现遇到了很多面试中常见的面试题,本部分主要是作者在 Github 等各大论坛收录的 JavaScript 相关知识和一些相关面试题时所做的笔记,分享这份总结给 ...

  6. CSS 是啥?前端小白入门级理解

    What is CSS? CSS stands for Cascading Style Sheets CSS describes how HTML elements are to be display ...

  7. 从零开始实现简单 RPC 框架 9:网络通信之心跳与重连机制

    一.心跳 什么是心跳 在 TPC 中,客户端和服务端建立连接之后,需要定期发送数据包,来通知对方自己还在线,以确保 TPC 连接的有效性.如果一个连接长时间没有心跳,需要及时断开,否则服务端会维护很多 ...

  8. IOS 集成 Bilibili IJKPlayer播放器,播放rtmp视频流

    因为公司项目需要,我一个连iPhone都没用过的人竟然跑去开发iOS APP.近一段时间一直忙于赶项目,到今天差不多了,所以记录一下当时遇到的各种坑,先从ios 集成 ijkplayer播放器说起! ...

  9. DataTable 增加、修改、删除

    using System; using System.Data; using System.Windows.Forms; using DotNet.Utilities; namespace Windo ...

  10. 尚硅谷Java基础学习笔记

    综述: Java学习图谱: 常见dos命令: 操作案例: Java语言的特点: 面向对象 两个基本概念:类.对象 三个基本特性:封装.继承.多态 健壮性.可继承性 write once,run any ...