title
solution
先说很神仙的结论构造:对于
a
i
a_i
ai,
a
i
=
v
i
∗
4
p
o
p
_
c
o
u
n
t
(
i
)
a_i=v_i*4^{pop\_count(i)}
ai=vi∗4pop_count(i),
b
b
b同理
c
i
=
∑
j
∣
k
=
i
a
i
∗
b
j
c_i=\sum_{j|k=i}a_i*b_j
ci=∑j∣k=iai∗bj,则
a
n
s
i
≡
c
i
4
p
o
p
_
c
o
u
n
t
(
i
)
m
o
d
4
ans_i\equiv \frac{c_i}{4^{pop\_count(i)}}\mod 4
ansi≡4pop_count(i)cimod4
证明:
p
o
p
_
c
o
u
n
t
(
i
)
+
p
o
p
_
c
o
u
n
t
(
j
)
≥
p
o
p
_
c
o
u
n
t
(
i
∣
j
)
pop\_count(i)+pop\_count(j)\ge pop\_count(i|j)
pop_count(i)+pop_count(j)≥pop_count(i∣j)
①
i
&
j
=
0
i\&j=0
i&j=0,对答案将有贡献
4
p
o
p
_
c
o
u
n
t
(
i
)
×
4
p
o
p
_
c
o
u
n
t
(
j
)
4
p
o
p
_
c
o
u
n
t
(
i
∣
j
)
=
1
\frac{4^{pop\_count(i)}\times 4^{pop\_count(j)}}{4^{pop\_count(i|j)}}=1
4pop_count(i∣j)4pop_count(i)×4pop_count(j)=1
②
i
&
j
≠
0
i\&j≠0
i&j=0,模
4
4
4为
0
0
0,无贡献
4
p
o
p
_
c
o
u
n
t
(
i
)
×
4
p
o
p
_
c
o
u
n
t
(
j
)
4
p
o
p
_
c
o
u
n
t
(
i
∣
j
)
=
4
x
,
x
∈
N
∗
\frac{4^{pop\_count(i)}\times 4^{pop\_count(j)}}{4^{pop\_count(i|j)}}=4^x,x∈N^*
4pop_count(i∣j)4pop_count(i)×4pop_count(j)=4x,x∈N∗
构造非常巧妙,一般来说是不可能自己想得出来的;这种结论都是难知道却好证
o(╥﹏╥)o I’m so vegetable!
code
#include <cstdio>
#define int long long
#define maxn 2100000
int n, N;
int a[maxn], b[maxn], c[maxn];
void FWT_or( int *v, int opt ) {
for( int i = 1;i < n;i <<= 1 )
for( int j = 0;j < n;j += ( i << 1 ) )
for( int k = 0;k < i;k ++ )
v[j + k + i] += opt * v[j + k];
}
signed main() {
scanf( "%d", &N );
n = 1 << N;
for( int i = 0;i < n;i ++ ) scanf( "%1lld", &a[i] );
for( int i = 0;i < n;i ++ ) scanf( "%1lld", &b[i] );
for( int i = 0;i < n;i ++ ) a[i] <<= ( __builtin_popcount( i ) << 1 );
for( int i = 0;i < n;i ++ ) b[i] <<= ( __builtin_popcount( i ) << 1 );
FWT_or( a, 1 ), FWT_or( b, 1 );
for( int i = 0;i < n;i ++ ) c[i] = a[i] * b[i];
FWT_or( c, -1 );
for( int i = 0;i < n;i ++ ) c[i] = c[i] >> ( __builtin_popcount( i ) << 1 ) & 3;
for( int i = 0;i < n;i ++ ) printf( "%lld", c[i] );
return 0;
}