HAOI2015
F[i,j] 表示以 i 为根的子树选了 j 个黑点,子树内的所有被标记过的路径权值和
void DFS(int p,int fa) { static LL tmp[maxn]; fill(dp[p]+2,dp[p]+n+1,-INF); size[p]=1; for(int i=start[p];i;i=next[i]) if(to[i]!=fa) { int q=to[i]; DFS(to[i],p); fill(tmp,tmp+size[p]+size[q]+1,-INF); for(int j=0;j<=size[p];++j) for(int k=0;k<=size[q];++k) tmp[j+k] = max(tmp[j+k],dp[p][j]+dp[q][k]+len[i]*(k*(m-k)+(size[q]-k)*(n-m-(size[q]-k)))); size[p]+=size[q]; for(int j=0;j<=size[p];++j) dp[p][j]=tmp[j]; } }
变换与变回:
for(int i=0;i<n;++i) for(int j=0;j<N;++j) if(j>>i&1) a[j]+=a[j^(1<<i)]; for(int i=0;i<n;++i) for(int j=0;j<N;++j) if(j>>i&1) a[j]-=a[j^(1<<i)];
orz gjy
需要的知识:容斥
T5
对于 f (n) 有 f(n) = ∑ f(i) (max(0 , n-m) <= i < n)
显然我们可以得到一个m * m的矩阵 A 来求得f(n)
因为矩阵具有分配律和可加性 所以有 A * (B+C) = A * B + A * C
A ^ (x1 + x2 + ...... xn) = A ^ x1 * A ^ x2 * ...... * A ^ xn
ans = ∑ (A * B) = ( ∑ A )* B
求 ∑A 时可以用dp
先预处理出每一段的 A^x 值记为seg[i,j]
状态转移: f[i]=∑ f[j] * seq[j+1][i] (j < i)
最后再乘上矩阵 B 就行了