CF1034E Little C Loves 3 III (estructura de hadas + convolución FWT_OR)

título

tema

solución

Permítanme hablar sobre la estructura de la conclusión de las hadas: para ai a_iayoAi = vi ∗ 4 pop _ count (i) a_i = v_i * 4 ^ {pop \ _count (i)}ayo=vyo4p o p _ c o u n t ( i )bbb同理
ci = ∑ j ∣ k = iai ∗ bj c_i = \ sum_ {j | k = i} a_i * b_jCyo=j | k = iayoBj, 则ansi ≡ ci 4 pop _ count (i) mod 4 ans_i \ equiv \ frac {c_i} {4 ^ {pop \ _count (i)}} \ mod 4a n syo4p o p _ c o u n t ( i )Cyom o d4

证明 :pop _ count (i) + pop _ count (j) ≥ pop _ count (i ∣ j) pop \ _count (i) + pop \ _count (j) \ ge pop \ _count (i | j)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 )
i & j = 0 i \ & j = 0i & j=0, 对 答案 将 有贡献
4 pop _ count (i) × 4 pop _ count (j) 4 pop _ count (i ∣ j) = 1 \ frac {4 ^ {pop \ _count (i)} \ times 4 ^ {pop \ _count (j)}} {4 ^ {pop \ _count (i | j)}} = 14p o p _ c o u n t ( i j )4p o p _ c o u n t ( i )×4p o p _ c o u n t ( j )=1
yo y j ≠ 0 yo \ y j ≠ 0i & j=0 , mod4 44 es0 00, 无 贡献
4 pop _ count (i) × 4 pop _ count (j) 4 pop _ count (i ∣ j) = 4 x, x ∈ N ∗ \ frac {4 ^ {pop \ _count (i)} \ veces 4 ^ {pop \ _count (j)}} {4 ^ {pop \ _count (i | j)}} = 4 ^ x, x∈N ^ *4p o p _ c o u n t ( i j )4p o p _ c o u n t ( i )×4p o p _ c o u n t ( j )=4x ,Xnorte∗ La
estructura es muy inteligente, y generalmente es imposible llegar a ella por ti mismo; este tipo de conclusión es difícil de saber pero
fácilde probaro (╥﹏╥) o ¡Soy tan vegetal!

código

#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;
}

Supongo que te gusta

Origin blog.csdn.net/Emm_Titan/article/details/115216035
Recomendado
Clasificación