【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6057

【题目大意】

  有 C[k]=∑_(i&j=k)A[i^j]*B[i|j]
  求 Ans=∑ C[i]*1526^i%998244353

【题解】

  将C[k]代入Ans的计算式得到 Ans=∑ A[i^j]*B[i|j]*1526^(i&j)%MOD
  我们发现(i^j)&(i&j)=0且(i^j)^(i&j)=i|j,
  因此bit[i^j]+bit[i&j]=bit[i|j],并有(i^j)|(i&j)=i|j
  设x=i^j, y=i&j, z=i|j 我们发现x&z=x,
  所以每对乘法乘上2^bit[x]的参数即可。
  我们计算1526^x和A[y]*2^bit[y]的or卷积,然后按位和B数组相乘。
  考虑bit[x]+bit[y]=bit[z]的卷积限制要求,我们将x和y按照bit进行分维,
  对于维度做和为bit[x]+bit[y]=bit[z]的子集FWT。

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int mod=998244353;
LL pow(LL a,LL b,LL p){LL t=1;for(a%=p;b;b>>=1LL,a=a*a%p)if(b&1LL)t=t*a%p;return t;}
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+d]=(x+y)%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+d]=(y-x+mod)%mod;
}
}
const int N=1<<20;
int n;
int A[21][N],B[21][N],C[21][N],bit[N],a[N],b[N],c[N];
int main(){
while(~scanf("%d",&n)){
int len=1<<n;
for(int i=0;i<len;i++)scanf("%d",&a[i]);
for(int i=0;i<len;i++)scanf("%d",&b[i]);
for(int i=0;i<len;i++)bit[i]=bit[i>>1]+(i&1);
memset(A,0,sizeof(A));
memset(B,0,sizeof(B));
memset(C,0,sizeof(C));
LL t=1;
for(int i=0;i<len;i++){
A[bit[i]][i]=1LL*a[i]*(1<<bit[i])%mod;
B[bit[i]][i]=t;
t=t*1526%mod;
}
for(int i=0;i<=n;i++){
FWT(A[i],len);
FWT(B[i],len);
}
for(int k=0;k<=n;k++){
for(int j=0;j+k<=n;j++){
for(int i=0;i<len;i++)C[j+k][i]=(C[j+k][i]+1LL*A[j][i]*B[k][i]%mod)%mod;
}
}
for(int i=0;i<=n;i++)UFWT(C[i],len);
for(int i=0;i<len;i++)c[i]=C[bit[i]][i];
LL ans=0;
for(int i=0;i<len;i++)ans=(ans+(1LL*c[i]*b[i])%mod)%mod;
printf("%d\n",ans);
}return 0;
}

HDU 6057 Kanade's convolution(FWT)的更多相关文章

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

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

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

  3. HDU 6057 - Kanade's convolution | 2017 Multi-University Training Contest 3

    /* HDU 6057 - Kanade's convolution [ FWT ] | 2017 Multi-University Training Contest 3 题意: 给定两个序列 A[0 ...

  4. 2017ACM暑期多校联合训练 - Team 3 1003 HDU 6058 Kanade's sum (模拟)

    题目链接 Problem Description Give you an array A[1..n]of length n. Let f(l,r,k) be the k-th largest elem ...

  5. HDU 6057 Kanade's convolution

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

  6. 【CF850E】Random Elections(FWT)

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

  7. 【CF662C】Binary Table(FWT)

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

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

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

  9. 【HDU5909】Tree Cutting(FWT)

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

随机推荐

  1. 将文件内容导入到MySQL中

    1.作用 把文件系统的内容导入到数据库中 2.语法 load data infile "文件名" into table 表名 fields terminated by " ...

  2. js中的apply、call、bind

    每个函数都包含两个非继承而来的方法,call()和apply(),可以改变函数内部this的指向 1.apply 用另一个对象替换当前对象,接收两个参数,第一个参数表示需要绑定的this变量,第二个参 ...

  3. Linux简介——(一)

    1. 常见操作系统 - 服务端操作系统 : linux.unix.windows server - 单机操作系统 : windows(dos .ucdos.win95.win98.win2000.xp ...

  4. 【转】linux下杀死进程

    经过搜集和整理相关的Linux操作系统杀死进程的材料,在这里给大家推荐本篇文章,希望大家看后会有不少收获. 1. kill 作用:根据进程号杀死进程 用法: kill [信号代码] 进程ID 举例: ...

  5. vuejs怎么在服务器部署?

    通过npm run build 把生成的dist文件夹(不要上传文件夹)里的内容上传到http服务器上就可以通过 http来访问了,开发机上正常,上传以后 程序出现错误不能运行的原因99.99%的可能 ...

  6. Linux信号函数

    1. signal函数: #include <signal.h> void (*signal(int signo, void (*func)(int)))(int); ret-成功返回信号 ...

  7. notifier chain — 内核通知链【转】

    转自:http://blog.csdn.net/g_salamander/article/details/8081724 大多数内核子系统都是相互独立的,因此某个子系统可能对其它子系统产生的事件感兴趣 ...

  8. linux内核启动分析(2)

    -----以下内容为从网络上整理所得------ 主要介绍kernel_init线程(函数),这个线程在rest_init函数中被创建,kernel_init函数将完成设备驱动程序的初始化,并调用in ...

  9. Git——Git常用命令速查表

  10. Redis -- 数据类型小结

    redis key 的命名规则: 对象类型:对象id:对象属性  (hset car:1: price 500.hset car:1: name:tom) 一.redis 数据类型: 1. 字符串类型 ...