题面

出自HDU6057

给你两个数列

A

[

0...

2

m

1

]

A[0...2^m-1]

A[0...2m−1] 和

B

[

0...

2

m

1

]

B[0...2^m-1]

B[0...2m−1]。

请计算数列

C

[

0...

2

m

1

]

C[0...2^m-1]

C[0...2m−1]:

C

[

k

]

=

i
  

a

n

d
  

j

=

k

A

[

i
  

x

o

r
  

j

]

B

[

i
  

o

r
  

j

]

C[k]=\sum_{i\;and\;j=k}A[i\;xor\;j]*B[i\;or\;j]

C[k]=iandj=k∑​A[ixorj]∗B[iorj]

你只需要输出

i

=

0

2

m

1

C

[

i

]

152

6

i

 ⁣ ⁣

m

o

d

  

998244353

\sum_{i=0}^{2^m-1}C[i]*1526^i\!\!\mod 998244353

∑i=02m−1​C[i]∗1526imod998244353

m

<

=

19

m <= 19

m<=19

0

A

[

i

]

,

B

[

i

]

<

998244353

0\leq A[i],B[i]<998244353

0≤A[i],B[i]<998244353

题解

公式中的条件让我们很想用快速沃尔什变换FWT,但是该公式和FWT基本式子大相径庭,无疑给我们造成了巨大的麻烦。

我们只有两条路可走,化式子,换元。

目前公式的形态想要化式子是毫无可能性的,我们只好先换元后再做打算。

我们知道,两个数异或、按位或、按位与三个运算是有等量关系的,即:

i
  

x

o

r
  

j

=

(

i
  

o

r
  

j

)

(

i
  

a

n

d
  

j

)

=

(

i
  

o

r
  

j

)

x

o

r

(

i
  

a

n

d
  

j

)

i\;xor\;j=(i\;or\;j)-(i\;and\;j)=(i\;or\;j)\,xor\,(i\;and\;j)

ixorj=(iorj)−(iandj)=(iorj)xor(iandj)

有了这个关系,我们就可以消去其中一个甚至两个运算,不妨设

x

=

i
  

x

o

r
  

j

,

y

=

i
  

o

r
  

j

x=i\;xor\;j,y=i\;or\;j

x=ixorj,y=iorj,则

x

=

y

(

i
  

a

n

d
  

j

)

=

y
  

x

o

r

(

i
  

a

n

d
  

j

)

x
  

x

o

r
  

y

=

(

i
  

a

n

d
  

j

)

x
  

x

o

r
  

y

=

k
      

(

x

y

,

x
  

a

n

d
  

y

=

x

)

x=y-(i\;and\;j)=y\;xor\,(i\;and\;j)\\ \Leftrightarrow x\;xor\;y=(i\;and\;j)\\ x\;xor\;y=k\;\;\;(x\subseteq y,即 x\;and\;y=x)

x=y−(iandj)=yxor(iandj)⇔xxory=(iandj)xxory=k(x⊆y,即xandy=x)

化到这一步,不免心中大喜,想要直接代成

C

[

k

]

=

x

x

o

r

y

=

k

A

[

x

]

B

[

y

]

C[k]=\sum_{x\,xor\,y=k}A[x]*B[y]

C[k]=∑xxory=k​A[x]∗B[y],并用类似子集卷积的方式限制位数来完成那热血沸腾的最后一步。

若真是这么简单,可就大错特错。这里有个坑,虽然有样例等各种数据的鼎力相助,发现这个坑对于OIer来说并不难,但当我们发现它,却着实令人倒吸一口凉气。

我们发现二元组

(

x

,

y

)

(x,y)

(x,y) 和

(

i

,

j

)

(i,j)

(i,j) 并不是一一对应!

没错,这有点令人吃惊,发现之初,甚至笔者有那么一瞬间考虑过重新化式子。这时候,冷静的思考就显得格外重要。重新化式子不是不可能,但无疑会令人士气大挫,想要再成功地化式子,除非是顶级高手,不然短时间内绝对办不到。沉吟片刻,我们自然而然地发现了其中的内在关系。

一对

(

x

,

y

)

(x,y)

(x,y) 对应的

(

i

,

j

)

(i,j)

(i,j) 不一定唯一,但它们的数量确是准确的

2

c

o

u

n

t

(

x

)

2^{count(x)}

2count(x)!

c

o

u

n

t

(

x

)

count(x)

count(x) 作为 x 中 1 的个数的定义不必多言,但为什么呢?

从定义入手,确定了 x 和 y 后,

i
  

a

n

d
  

j

i\;and\;j

iandj 就可以确定了,也就是说我们已经确定了

i

i

i 和

j

j

j 中共有的 1 是哪些,这是唯一的,那么接下来 x (

i
  

x

o

r
  

j

i\;xor\;j

ixorj)则确定了

i

i

i 和

j

j

j 中只有其一拥有的 1 的分布,这是不定的,既然这其中任意一个 1 既有可能属于

i

i

i ,又有可能属于

j

j

j ,那么总数不就自然是

2

c

o

u

n

t

(

x

)

2^{count(x)}

2count(x) 了吗?

打通了阻碍后,接下来的化式子便水到渠成:

C

[

k

]

=

x

x

o

r

y

=

k

A

[

x

]

B

[

y

]

2

c

o

u

n

t

(

x

)

                    

=

x

x

o

r

y

=

k

(

A

[

x

]

2

c

o

u

n

t

(

x

)

)

B

[

y

]

(

x

y

)

\begin{matrix}C[k]=\sum_{x\,xor\,y=k}A[x]*B[y]*2^{count(x)}\\ \;\;\;\;\;\;\;\;\;\;=\sum_{x\,xor\,y=k}(A[x]*2^{count(x)})*B[y]\\ (x\subseteq y)\end{matrix}

C[k]=∑xxory=k​A[x]∗B[y]∗2count(x)=∑xxory=k​(A[x]∗2count(x))∗B[y](x⊆y)​
终于长舒一口气,我们可以用代码去演绎了……

(最近小说看的有点多,啰嗦了点,但思路应该比较清晰)

CODE

顺便把FWT全模板附在代码里了,可能与笔者自己的学习笔记有点出入,但无大碍。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN (1<<20|5)
#define LL long long
#define DB double
#define ENDL putchar('\n')
#define lowbit(x) (-(x) & (x))
LL read() {
LL f=1,x=0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
char readchar() {
char s = getchar();while(s == ' ' || s == '\n') s = getchar();
return s;
}
const int MOD = 998244353;
const int inv2 = 998244354/2;
int n,m,i,j,s,o,k;
//----------------------FWT start-------------------------
int qm(int a,int M) {return (a>M? a-M:a);}
void DWTOR(int *s,int n) {
for(int k = 1;k < n;k <<= 1) {
for(int j = 0;j < n;j += (k<<1)) {
for(int i = j;i < j+k;i ++) {
(s[i+k] += s[i]) %= MOD;
}
}
}return ;
}
void IDWTOR(int *s,int n) {
for(int k = n/2;k > 0;k >>= 1) {
for(int j = 0;j < n;j += (k<<1)) {
for(int i = j;i < j+k;i ++) {
(s[i+k] += MOD-s[i]) %= MOD;
}
}
}return ;
} void DWTAND(int *s,int n) {
for(int k = 1;k < n;k <<= 1) {
for(int j = 0;j < n;j += (k<<1)) {
for(int i = j;i < j+k;i ++) {
(s[i] += s[i+k]) %= MOD;
}
}
}return ;
}
void IDWTAND(int *s,int n) {
for(int k = n/2;k > 0;k >>= 1) {
for(int j = 0;j < n;j += (k<<1)) {
for(int i = j;i < j+k;i ++) {
(s[i] += MOD-s[i+k]) %= MOD;
}
}
}return ;
} void DWTXOR(int *s,int n) {
for(int k = 1;k < n;k <<= 1) {
for(int j = 0;j < n;j += (k<<1)) {
for(int i = j;i < j+k;i ++) {
int A = s[i],B = s[i+k];
s[i] = qm((A + B) , MOD);
s[i+k] = qm((A +MOD- B) , MOD);
}
}
}return ;
}
void IDWTXOR(int *s,int n) {
for(int k = n/2;k > 0;k >>= 1) {
for(int j = 0;j < n;j += (k<<1)) {
for(int i = j;i < j+k;i ++) {
int A = s[i],B = s[i+k];
s[i] = qm((A + B) , MOD) *1ll*inv2 % MOD;
s[i+k] = qm((A +MOD- B) , MOD) *1ll*inv2 % MOD;
}
}
}return ;
}
//----------------------FWT end---------------------------
int ct[MAXN],po[MAXN];
int A[21][MAXN],B[21][MAXN],C[21][MAXN];
int aa[MAXN],bb[MAXN],cc[MAXN];
int main() {
n = read();m = (1<<n);
po[0] = 1;
for(int i = 1;i < m;i ++) {
ct[i] = ct[i - lowbit(i)] + 1;
po[i] = po[i - 1] * 1526ll % MOD;
}
for(int i = 0;i < m;i ++) A[ct[i]][i] = read()*(1ll<<ct[i]) % MOD;
for(int i = 0;i < m;i ++) B[ct[i]][i] = read();
for(int i = 0;i <= n;i ++) DWTXOR(A[i],m),DWTXOR(B[i],m);
for(int i = 0;i <= n;i ++) {
for(int j = i;j <= n;j ++) {
for(int k = 0;k < m;k ++) {
(C[i][k] += A[j-i][k] *1ll* B[j][k] % MOD) %= MOD;
}
}
IDWTXOR(C[i],m);
}
int ans = 0;
for(int i = 0;i < m;i ++) {
(ans += C[ct[i]][i] *1ll* po[i] % MOD) %= MOD;
}
printf("%d\n",ans);
return 0;
}

[HDU6057] Kanade‘s convolution (FWT)的更多相关文章

  1. HDU 6057 Kanade's convolution(FWT)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6057 [题目大意] 有 C[k]=∑_(i&j=k)A[i^j]*B[i|j] 求 Ans ...

  2. hdu6057 Kanade's convolution 【FWT】

    题目链接 hdu6057 题意 给出序列\(A[0...2^{m} - 1]\)和\(B[0...2^{m} - 1]\),求所有 \[C[k] = \sum\limits_{i \; and \; ...

  3. 【CF850E】Random Elections(FWT)

    [CF850E]Random Elections(FWT) 题面 洛谷 CF 题解 看懂题就是一眼题了... 显然三个人是等价的,所以只需要考虑一个人赢了另外两个人就好了. 那么在赢另外两个人的过程中 ...

  4. 【CF662C】Binary Table(FWT)

    [CF662C]Binary Table(FWT) 题面 洛谷 CF 翻译: 有一个\(n*m\)的表格(\(n<=20,m<=10^5\)), 每个表格里面有一个\(0/1\), 每次可 ...

  5. 「WC2018」州区划分(FWT)

    「WC2018」州区划分(FWT) 我去弄了一个升级版的博客主题,比以前好看多了.感谢 @Wider 不过我有阅读模式的话不知为何 \(\text{LATEX}\) 不能用,所以我就把这个功能删掉了. ...

  6. 【HDU5909】Tree Cutting(FWT)

    [HDU5909]Tree Cutting(FWT) 题面 vjudge 题目大意: 给你一棵\(n\)个节点的树,每个节点都有一个小于\(m\)的权值 定义一棵子树的权值为所有节点的异或和,问权值为 ...

  7. 【UOJ#310】【UNR#2】黎明前的巧克力(FWT)

    [UOJ#310][UNR#2]黎明前的巧克力(FWT) 题面 UOJ 题解 把问题转化一下,变成有多少个异或和为\(0\)的集合,然后这个集合任意拆分就是答案,所以对于一个大小为\(s\)的集合,其 ...

  8. Codeforces663E Binary Table(FWT)

    题目 Source http://codeforces.com/contest/663/problem/E Description You are given a table consisting o ...

  9. Paper | Octave Convolution(OctConv)

    目录 1. 尺度空间理论(scale-space theory) 2. OctConv 3. 启发 论文:Drop an Octave: Reducing Spatial Redundancy in ...

随机推荐

  1. GIF录制工具下载

    GIF录制工具(GifCam)下载地址: https://files.cnblogs.com/files/blogs/747754/GifCam.rar

  2. .NET中的 Count()、Count、Length 有什么不同

    更新记录 2022年4月16日:本文迁移自Panda666原博客,原发布时间:2021年7月15日. Count().Count.Length,都用于获得序列长度或者说元素的个数,但它们有什么明确的区 ...

  3. SmartIDE v0.1.19 - 码云(Gitee)最有价值开源项目奖项、工作区策略、类虚拟机镜像VMLC、Server安装手册

    SmartIDE v0.1.19 (CLI Build 3909, Server Build 3890) 已经发布,本次Sprint主要完成2个重要特性,工作区策略和类虚拟机容器(VM Like Co ...

  4. electron-vue 项目启动动态获取配置文件中的后端服务地址

    前言 最近的项目迭代中新增一个需求,需要在electron-vue 项目打包之后,启动exe 可执行程序的时候,动态获取配置文件中的 baseUrl 作为服务端的地址.electron 可以使用 no ...

  5. BUUCTF-穿越时空的思念

    穿越时空的思念 音频题的话一般是摩尔斯电码,软件打开音频发现 短的为. 长的为- 空缺的为空格 ..-. ----- ..--- ----. -... -.. -.... ..-. ..... ... ...

  6. RPA应用场景-银行回单查询

    场景概述银行回单查询 所涉系统名称银行网银 人工操作(时间/次) 5 分钟 所涉人工数量 4 操作频率不定时 场景流程 1.收到外派业务员申请查询收入银行回单的邮件: 2.依据邮件中提供的客户信息进入 ...

  7. 基于Vue2.x的前端架构,我们是这么做的

    通过Vue CLI可以方便的创建一个Vue项目,但是对于实际项目来说还是不够的,所以一般都会根据业务的情况来在其基础上添加一些共性能力,减少创建新项目时的一些重复操作,本着学习和分享的目的,本文会介绍 ...

  8. Python实现中文字幕雨+源代码

    写在前面的一些P话: 最近浏览了很多关于用Python和Pygame实现代码雨的案例,发现很多都是没有深入讲解代码的整个实现过程,从0到1教会你制作中文文字雨. 然后在介绍的过程中,我也将深入介绍Py ...

  9. 【python基础】第19回 多层,有参装饰器 递归 二分法

    本章内容概要 1. 多层装饰器 2. 有参装饰器 3. 递归函数 4. 算法(二分法) 本章内容详解 1. 多层装饰器 1.1 什么是多层装饰器 多层装饰器是从下往上依次执行,需要注意的是,被装饰的函 ...

  10. Tapdata x 轻流,为用户打造实时接入轻流的数据高速通道

      在全行业加速布局数字化的当口,如何善用工具,也是为转型升级添薪助力的关键一步.   那么当轻量的异构数据实时同步工具,遇上轻量的数字化管理工具,将会收获什么样的新体验?此番 Tapdata 与轻流 ...