题目
点这里看题目。
分析
设 c o u n t ( x ) count(x) count(x)为 x x x的二进制中 1 1 1的个数。因此 f ( u , v ) = c o u n t ( u ⊕ v ) f(u,v)=count(u\oplus v) f(u,v)=count(u⊕v)
看一看每次转移,我们发现最不友好的东西就是 f ( u , v ) f(u,v) f(u,v),因此我们得想办法把它从我们的计算中丢掉。
发现对于 [ 0 , n ) [0,n) [0,n)中的所有数,两两异或之后不会超过 n n n。并且对于一个固定的数 x x x,其 c o u n t ( x ) count(x) count(x)是不会变的。因此我们考虑将 b b b数组转存出来:
a [ i ] = b [ c o u n t ( i ) ] a[i]=b[count(i)] a[i]=b[count(i)]
因此有:
e [ u ] = ∑ v a [ u ⊕ v ] e [ v ] e[u]=\sum_v a[u\oplus v]e[v] e[u]=v∑a[u⊕v]e[v]
考虑改变枚举顺序:
e [ u ] =