hdu 6057 Kanade's convolution(子集卷积)
2024-08-28 06:44:23
题解:
然后就是接下来如何fwt
也就是如何处理bit(x) - bit(y) = bit(k)这个条件。
其实就是子集卷积。
把bit(x)和bit(y)划分成两个集合,然后就是子集卷积的形式。
这里设两个新的数组 A[bit(y)][y], B[bit(x)][x],代表拆出来的相应数组
然后对这两个数组做fwt,得到其点值表示,然后直接在外层枚举x和y的大小然后做卷积即可。
这样说可能很抽象,其实贴出代码就很清楚了
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
const int MOD = ;
typedef long long LL;
LL mypow(LL a, LL b){
LL ans = ; for(; b; b >>= ) { if(b&) (ans *= a) %= MOD; (a *= a) %= MOD; } return ans;
}
LL I2 = mypow(, MOD-);
const int maxn = (<<) + ;
LL a[maxn], b[maxn], A[][maxn*], B[][maxn*], C[][maxn*];
vector<int> Bit[];
int m; class FWT{
public:
void fwt(LL *a, int n){
for(int d = ; d < n; d <<= ){
for(int m = d<<, i = ; i < n; i += m){
for(int j = ; j < d; j++){
LL x = a[i+j], y = a[i+j+d];
a[i+j] = x+y; if(a[i+j] >= MOD) a[i+j] -= MOD;
a[i+j+d] = x-y; if(a[i+j+d] < ) a[i+j+d] += MOD;
}
}
}
}
void ufwt(LL *a, int n){
for(int d = ; d < n; d <<= ){
for(int m = d<<, i = ; i < n; i += m){
for(int j = ; j < d; j++){
LL x = a[i+j], y = a[i+j+d];
a[i+j] = (x+y)*I2%MOD; a[i+j+d] = (x-y+MOD)*I2%MOD;
}
}
}
}
void work(LL *a, LL *b, int n){
fwt(a, n);
fwt(b, n);
for(int i = ; i < n; i++) a[i] *= b[i];
ufwt(a, n);
}
}myfwt; int bit(int x){
int ans = ;
for(int i = ; i < ; i++)
ans += ((x&(<<i)) > );
return ans;
} int main()
{
for(int i = ; i < (<<); i++) Bit[bit(i)].push_back(i);
cin>>m;
for(int i = ; i < (<<m); i++) scanf("%d", &a[i]);
for(int i = ; i < (<<m); i++) scanf("%d", &b[i]);
int L = (<<m);
for(int i = ; i <= m; i++){
for(auto x : Bit[i]){
if(x >= L) break;
A[i][x] = (a[x]*(<<i))%MOD;
B[i][x] = b[x];
}
myfwt.fwt(A[i], L);
myfwt.fwt(B[i], L);
}
for(int x = ; x <= m; x++)
for(int y = ; y <= x; y++)
for(int i = ; i < L; i++)
(C[x-y][i] += A[y][i]*B[x][i]) %= MOD;
for(int i = ; i <= m; i++) myfwt.ufwt(C[i], L);
LL ans = , t = ;
for(int i = ; i < (<<m); i++){
(ans += C[bit(i)][i]*t) %= MOD;
(t *= ) %= MOD;
}
cout<<ans<<endl;
return ;
}
最新文章
- Android隐藏标题栏和状态栏
- visual studio 2012 插件
- MSSQL获得表的字段名称及其参数
- Access数据库导入到SQL Server 2005 Express中
- dup2()函数的使用,
- asp.net mvc源码分析-Action篇 IModelBinder
- Swift学习笔记四
- openvswitch安装、基本操作
- Linux 网络编程: echo Service
- sublime自定义配置
- 集美大学网络1413第十四次作业成绩(团队九) -- 测试与发布&;博客展示(Beta版本)
- Lavarel artisan 命令
- LeetCode专题-Python实现之第21题:Merge Two Sorted Lists
- kubernetes进阶之一:简单例子
- Redis自学笔记:2.准备
- SDN网络虚拟化、资源映射等相关论文粗读
- Python内置类型——set
- Oracle SQL语句执行步骤
- c# 实现查找mysql安装路径
- 2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017) Solution