CF1034E Little C Loves 3 III【子集卷积,位运算】
模 \(4\) 子集卷积。
\(n\le 21,\text{TL}=1\text s\)。
在占位集合幂级数的多项式一维代入 \(y=4\) 即可。直接自然溢出啥事没有。时间复杂度 \(O(n2^n)\)。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
const int N = 1<<21;
int n, m, siz[N]; LL a[N], b[N];
int main(){
scanf("%d", &n); m = 1<<n;
for(int i = 1;i < m;++ i) siz[i] = siz[i>>1] + (i&1);
for(int i = 0;i < m;++ i){
int ch = getchar();
while(ch < '0' || ch > '3') ch = getchar();
a[i] = LL(ch^'0')<<(siz[i]<<1);
}
for(int i = 0;i < m;++ i){
int ch = getchar();
while(ch < '0' || ch > '3') ch = getchar();
b[i] = LL(ch^'0')<<(siz[i]<<1);
}
for(int mid = 1;mid < m;mid <<= 1)
for(int i = 0;i < m;i += mid<<1)
for(int j = 0;j < mid;++ j){
a[mid+i+j] += a[i+j];
b[mid+i+j] += b[i+j];
}
for(int i = 0;i < m;++ i) a[i] *= b[i];
for(int mid = 1;mid < m;mid <<= 1)
for(int i = 0;i < m;i += mid<<1)
for(int j = 0;j < mid;++ j)
a[mid+i+j] -= a[i+j];
for(int i = 0;i < m;++ i) putchar('0' ^ (a[i]>>(siz[i]<<1)&3));
}