题目链接

hdu6057

题意

给出序列\(A[0...2^{m} - 1]\)和\(B[0...2^{m} - 1]\),求所有

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

题解

我只能感叹太神了

看到题目我是懵逼的

首先注意三者运算的关系:

\[(i \; and \; j) + (i \; xor \; j) = (i \; or \; j)
\]

证明显然

于是我们枚举\(x = i \; or \; j,y = i \; xor \; j\),显然\(y \in x\)即\(x \; and \; y = y\)

且对于同一个\(x,y\),这样的\(i,j\)存在\(2^{bit(y)}\)对,\(bit(y)\)指\(y\)二进制下\(1\)的个数

证明显然

于是我们有

\[\begin{aligned}
C[k] &= \sum\limits_{i \; and \; j = k} A[i \; xor \; j]B[i \; or \; j] \\
&= \sum\limits_{x - y = k} [x \; and \; y = y]B[x]A[y]2^{bit(y)} \\
&= \sum\limits_{x \; xor \; y = k} [bit(x) - bit(y) = bit(k)]B[x]A[y]2^{bit(y)} \\
\end{aligned}
\]

除去中间那个限制,就是一个异或卷积了

考虑如何去掉中间的限制,我们只需将\(bit()\)不同的位置分离,分别做\(FWT\)

即设\(F(A,x)_{i} = [bit(i) = x]A_i\)

那么有

\[F(C,k) = \sum\limits_{i = k}^{m} F(B,i) \times F(A,i - k)
\]

然后\(C[k]\)的结果就存在\(F(C,bit(k))\)中

复杂度\(O(m^2 2^{m})\)

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define cls(s,v) memset(s,v,sizeof(s))
#define mp(a,b) make_pair<int,int>(a,b)
#define cp pair<int,int>
using namespace std;
const int maxn = (1 << 19),maxm = 100005,INF = 0x3f3f3f3f;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
return flag ? out : -out;
}
const int P = 998244353;
int m,A[21][maxn],B[21][maxn],C[21][maxn],a[maxn],b[maxn],inv2,deg;
inline int qpow(int a,int b){
int re = 1;
for (; b; b >>= 1,a = 1ll * a * a % P)
if (b & 1) re = 1ll * re * a % P;
return re;
}
inline int bit(int x){int re = 0; while (x) re += (x & 1),x >>= 1; return re;}
inline void fwt(int* a,int n,int f){
for (int i = 1; i < n; i <<= 1)
for (int j = 0; j < n; j += (i << 1))
for (int k = 0; k < i; k++){
int x = a[j + k],y = a[j + k + i];
a[j + k] = (x + y) % P,a[j + k + i] = (x - y + P) % P;
if (f == -1) a[j + k] = 1ll * a[j + k] * inv2 % P,a[j + k + i] = 1ll * a[j + k + i] * inv2 % P;
}
}
int main(){
inv2 = qpow(2,P - 2);
m = read(); deg = (1 << m); int x;
for (int i = 0; i < deg; i++){
a[i] = read(); x = bit(i);
A[x][i] = 1ll * a[i] * qpow(2,x) % P;
}
for (int i = 0; i < deg; i++){
b[i] = read();
B[bit(i)][i] = b[i];
}
for (int i = 0; i <= m; i++){
fwt(A[i],deg,1);
fwt(B[i],deg,1);
}
for (int k = 0; k <= m; k++){
for (int x = k; x <= m; x++)
for (int i = 0; i < deg; i++)
C[k][i] = (C[k][i] + 1ll * B[x][i] * A[x - k][i] % P) % P;
}
for (int i = 0; i <= m; i++) fwt(C[i],deg,-1);
int ans = 0,tmp = 1;
for (int i = 0; i < deg; i++)
ans = (ans + 1ll * C[bit(i)][i] * tmp % P) % P,tmp = 1ll * tmp * 1526 % P;
printf("%d\n",ans);
return 0;
}

hdu6057 Kanade's convolution 【FWT】的更多相关文章

  1. [HDU6057] Kanade‘s convolution (FWT)

    题面 出自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[ ...

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

  3. LOJ2269 [SDOI2017] 切树游戏 【FWT】【动态DP】【树链剖分】【线段树】

    题目分析: 好题.本来是一道好的非套路题,但是不凑巧的是当年有一位国家集训队员正好介绍了这个算法. 首先考虑静态的情况.这个的DP方程非常容易写出来. 接着可以注意到对于异或结果的计数可以看成一个FW ...

  4. CSU1911 Card Game 【FWT】

    题目链接 CSU1911 题解 FWT模板题 #include<algorithm> #include<iostream> #include<cstdlib> #i ...

  5. BZOJ4589 Hard Nim 【FWT】

    题目链接 BZOJ4589 题解 FWT 模板题 #include<algorithm> #include<iostream> #include<cstdlib> ...

  6. [JZOJ6088] [BZOJ5376] [loj #2463]【2018集训队互测Day 1】完美的旅行【线性递推】【多项式】【FWT】

    Description Solution 我们考虑将问题一步步拆解 第一步求出\(F_{S,i}\)表示一次旅行按位与的值为S,走了i步的方案数. 第二步答案是\(F_{S,i}\)的二维重复卷积,记 ...

  7. 【杂题】[AGC034F] RNG and XOR【集合幂级数】【FWT】【DP】

    Description 你有一个随机数生成器,它会以一定的概率生成[0,2^N-1]中的数,每一个数的概率是由序列A给定的,Pi=Ai/sum(Ai) 现在有一个初始为0的数X,每一轮随机生成一个数v ...

  8. CF662C Binary Table【FWT】

    CF662C Binary Table 题意: 给出一个\(n\times m\)的\(01\)矩阵,每次可以反转一行或者一列,问经过若干次反转之后,最少有多少个\(1\) \(n\le 20, m\ ...

  9. CF1119H-Triple【FWT】

    正题 题目链接:https://www.luogu.com.cn/problem/CF1119H 题目大意 \(n\)个可重集,第\(i\)个里有\(x\)个\(a_i\),\(y\)个\(b_i\) ...

随机推荐

  1. webpack3升级为webpack4

    写在前面的话:为什么要升级,因为公司目前的项目使用webpack3,但是因为是多页应用,入口估计有一百多个,开发模式下慢得不像话,修改一个文件需要十几秒才编译好,之前的解决方案是减少入口,但是要调试其 ...

  2. ubuntu HackRF One相关环境搭建

    本文内容.开发板及配件仅限用于学校或科研院所开展科研实验! 淘宝店铺名称:开源SDR实验室 HackRF链接:https://item.taobao.com/item.htm?spm=a1z10.1- ...

  3. 【Python3.6】python打包成exe

    D:\python_test>pip3 install pyinstaller…………D:\python_test>pyinstaller -F -w ui.py INFO: PyInst ...

  4. python数据分析系列(2)--numpy

    NumPy(Numerical Python的简称)是Python数值计算最重要的基础包.大多数提供科学计算的包都是用NumPy的数组作为构建基础. NumPy的部分功能如下: ndarray,一个具 ...

  5. init命令详解

    基础命令学习目录首页 1.手动输入命令会执行相关操作   #init 0 - 停机(千万不能把initdefault 设置为0 )   #init 1 - 单用户模式   #init 2 - 多用户, ...

  6. dobule运算

    DecimalFormat df = new DecimalFormat("0.00"); double rate = (warnMonNum/totalCustCount)*10 ...

  7. 使用谷歌浏览器调试WEB前端的一些必备调试技巧

    转载:http://www.techug.com/post/chrome-debug-tips.html Chrome的开发者工具是个很强大的东西,相信程序员们都不会陌生,不过有些小功能可能并不为大众 ...

  8. JavaWeb项目通过调用cmd实现备份数据库的功能

    1.别急着上车,先测试一下能否成功调用cmd,可以尝试通过cmd命令打开计算器,代码如下:     2.能成功打开计算器后,证明调用cmd的方法是没错的,现在把cmd命令字符串改成我们备份数据库的 命 ...

  9. 第十次PSP

  10. OO学习体会与阶段总结(设计与实现)

    前言   在最近的一个月的课程中,笔者对于规格化编程进行了深入的学习.运用面向对象抽象思想对编写的程序进行过程抽象.异常处理.数据抽象.类的层次规格与迭代等等规格设计,使得程序结构化程度提高,具有更好 ...