/*
HDU 6057 - Kanade's convolution [ FWT ] | 2017 Multi-University Training Contest 3
题意:
给定两个序列 A[0...2^m-1], B[0...2^m-1]
求 C[0...2^m-1] ,满足:
C[k] = ∑[i&j==k] A[i^j] * B[i|j]
m <= 19
分析:
看C[k]的形式与集合卷积的形式接近,故转化式子时主要向普通的集合卷积式方向靠
与三种位运算都相关的结论是 : i^j + i&j = i|j
设 x = i^j, y = i|j,则显然 k = y-x,且 k 与 x 互成关于 y 的补集,即 k = x^y 再来关心给定(x,y),符合 x = i^j, y = i|j的(i,j)对的数目
注意到相同的位 i&j 是确定的,x = i^j 是i和j不同的位的数目,这部分谁是 0 谁是 1 不固定
故(i,j)对的数目为 2^bits(x) 此时重写原式: C[k] = ∑ [k == x^y] [k == y-x] A[x]*2^bits(x) * B[y] 设 A'[x] = A[x]*2^bits(x)
由于 [k == x^y],第二个条件 [k == y-x] 等价于 bits(k) == bits(y) - bits(x)
C[k] = ∑ [k == x^y] [bits(k) == bits(x) - bits(y)] A'[x] * B[y] 将 A,B,C三个数组按 bits 划分:
C[bits(k)][k] = ∑ [k == x^y] A[bits(x)][x]*2^bits(x) * B[bits(y)][y] 最后按不同的维度(bits)做 FWT即可
*/
#include <bits/stdc++.h>
using namespace std;
const int MOD = 998244353;
const int N = 1<<20;
int rev2;
long long inv( long long a , long long m)
{
if (a == 1) return 1;
return inv(m%a, m) * (m - m/a) % m;
}
void FWT(int a[], int n) {
for (int d = 1; d < n; d <<= 1)
for (int m = d<<1, i = 0; i < n; i += m)
for (int j = 0; j < d; j++)
{
int x = a[i+j], y = a[i+j+d];
a[i+j] = (x+y) % MOD;
a[i+j+d] = (x-y+MOD) % MOD;
}
}
void UFWT(int a[], int n) {
for (int d = 1; d < n; d <<= 1)
for (int m = d<<1, i = 0; i < n; i += m)
for (int j = 0; j < d; j++)
{
int x = a[i+j], y = a[i+j+d];
a[i+j] = 1LL*(x+y) * rev2 % MOD;
a[i+j+d] = (1LL*(x-y)*rev2 % MOD + MOD) % MOD;
}
}
int a[20][N], b[20][N], c[20][N];
int bits[N];
int m, n;
void init()
{
rev2 = inv(2, MOD);
bits[0] = 0;
for (int i = 1; i < N; i++) bits[i] = bits[i>>1] + (i&1);
}
int main()
{
init();
scanf("%d", &m);
n = 1<<m;
for (int i = 0; i < n; i++)
{
int x; scanf("%d", &x);
a[bits[i]][i] = 1LL*x * (1<<bits[i]) % MOD;
}
for (int i = 0; i < n; i++)
{
int x; scanf("%d", &x);
b[bits[i]][i] = x;
}
for (int i = 0; i <= m; i++) FWT(a[i], n);
for (int i = 0; i <= m; i++) FWT(b[i], n);
for (int i = 0; i <= m; i++)
for (int j = i; j <= m; j++)
for (int k = 0; k < n; k++)
{
c[j-i][k] = (c[j-i][k] + 1LL*a[i][k] * b[j][k] % MOD) % MOD;
}
for (int i = 0; i <= m; i++) UFWT(c[i], n);
long long ans = 0, base = 1;
for (int i = 0; i < n; i++)
{
ans = ( ans + c[bits[i]][i] * base % MOD ) % MOD;
base = base * 1526 % MOD;
}
printf("%lld\n", ans);
}

  

HDU 6057 - Kanade's convolution | 2017 Multi-University Training Contest 3的更多相关文章

  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. HDU 6057 Kanade's convolution

    题目链接:HDU-6057 题意: 思路:先按照官方题解推导出下面的式子: 现在唯一的问题就是怎么解决[bit(x)-bit(y)=bit(k)]的问题. 我们定义\( F(A,k)_{i}=\lef ...

  3. hdu 6057 Kanade's convolution(子集卷积)

    题解: 然后就是接下来如何fwt 也就是如何处理bit(x) - bit(y) = bit(k)这个条件. 其实就是子集卷积. 把bit(x)和bit(y)划分成两个集合,然后就是子集卷积的形式. 这 ...

  4. HDU 6059 - Kanade's trio | 2017 Multi-University Training Contest 3

    思路来自题解(看着题解和标程瞎吉尔比划了半天) /* HDU 6059 - Kanade's trio [ 字典树 ]  |  2017 Multi-University Training Conte ...

  5. HDU 6058 - Kanade's sum | 2017 Multi-University Training Contest 3

    /* HDU 6058 - Kanade's sum [ 思维,链表 ] | 2017 Multi-University Training Contest 3 题意: 给出排列 a[N],求所有区间的 ...

  6. HDU 6162 - Ch’s gift | 2017 ZJUT Multi-University Training 9

    /* HDU 6162 - Ch’s gift [ LCA,线段树 ] | 2017 ZJUT Multi-University Training 9 题意: N节点的树,Q组询问 每次询问s,t两节 ...

  7. HDU 6058 Kanade's sum —— 2017 Multi-University Training 3

    Kanade's sum Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  8. 2017 Wuhan University Programming Contest (Online Round) Lost in WHU 矩阵快速幂 一个无向图,求从1出发到达n最多经过T条边的方法数,边可以重复经过,到达n之后不可以再离开。

    /** 题目:Lost in WHU 链接:https://oj.ejq.me/problem/26 题意:一个无向图,求从1出发到达n最多经过T条边的方法数,边可以重复经过,到达n之后不可以再离开. ...

  9. 2017 Wuhan University Programming Contest (Online Round) C. Divide by Six 分析+模拟

    /** 题目:C. Divide by Six 链接:https://oj.ejq.me/problem/24 题意:给定一个数,这个数位数达到1e5,可能存在前导0.问为了使这个数是6的倍数,且没有 ...

随机推荐

  1. Design In-Memory File System

    Design an in-memory file system to simulate the following functions: ls: Given a path in string form ...

  2. PowerPoint储存此文件时发生错误 出现错误的问题解决方法

    .单击“文件”,单击“选项”,然后单击“加载项”. . 在管理下拉框中选择“COM加载项”,单击“转到”按钮. . 检查是否存在有任何加载项,清除所有复选框来禁用它们. . 关闭PPT并重新启动,测试 ...

  3. [转]史上最最最详细的手写Promise教程

    我们工作中免不了运用promise用来解决异步回调问题.平时用的很多库或者插件都运用了promise 例如axios.fetch等等.但是你知道promise是咋写出来的呢? 别怕-这里有本promi ...

  4. 【Jmeter源码解读】001——目录结构

    1.顶层目录 bin - 包含.bat 和 . sh 这些文件用于启动JMeter.同时也包含了ApacheJmeter.jar 和 相关的配置文件 build - build 脚本创建的目录,存放一 ...

  5. Mac安装postgresql和卸载PostgreSQL

    1.homebrew安装 brew install postgresql 2.初始化 initdb /usr/local/var/postgres 3.创建数据库及查看数据库 (1)先创建db. cr ...

  6. (三)mybatis 的使用(入门)

    目录 mybatis 的使用 -- 准备 mybatis 的使用 -- 搭建好工程结构 mybatis 的使用 -- 创建 sqlMapCnfig.xml 全局配置文件 mybatis 的使用 -- ...

  7. Ural 1248 Sequence Sum 题解

    目录 Ural 1248 Sequence Sum 题解 题意 题解 程序 Ural 1248 Sequence Sum 题解 题意 给定\(n\)个用科学计数法表示的实数\((10^{-100}\s ...

  8. C++ 继承 - 在派生类中对基类初始化

    构造函数与基类的其他成员不同,不能被派生类继承,因此为了初始化基类中的成员变量,需要在派生类中调用基类的构造函数(即显式调用),如果派送类没有调用则默认调用基类的无参构造函数(即隐式调用). 显式调用 ...

  9. hdu 2609 字符串最小表示法 虽然不是很懂 还是先贴上来吧。/,。/

    还需要再消化一下这个算法.. 今天没有时间了,, 六级过了 就有大把时间 快活啊!#include<iostream> #include<cstdio> #include< ...

  10. 缩放动画(ScaleTransform)

    在Silverlight的动画框架中,ScaleTransform类提供了在二维空间中的坐标内进行缩放操作,通过ScaleTransform可以在水平或垂直方向的缩放和拉伸对象,以实现一个简单的缩放动 ...