codeforces Round#332Div2 题解
codeforces Round#332Div2
AB
签到题
比较激动,纷纷WA了一发。
C
- 把数组
h
复制给a
,然后对a
数组排序。 - 对
h
和a
数组,求前缀和,有多少个位置满足\(\sum a[i] = \sum h[i]\), 就最多能分成多少块。
D
- 我们枚举更短的那条边,这样的边不会太多。
- 然后求,更长的那条边。
E
符合xxx限定条件的图的计数问题。数据范围很状压。
我们用dp[mask][root]
表示,集合mask
里的点,以root
为根,不违背限定条件的方案数。
接下来考虑dp[mask][root]
是怎样转移而来的。
设x
为集合mask - {root}
中最小的元素。
枚举包含元素x
的mask
的子集newmask
作为root
的一棵子树。
然后我们可以在newmask
中选择一个根newroot
.
接下来我们判断,枚举的newmask
,newroot
是否合法。
对于一条已知的边。
u!=root,v!=root
,如果u
在newmask
中,v
不在newmask
中,则不合法。- 与
root
相连的,且在newmask
中的点,至多只有一个【root
最多只能和newmask
中的一个点相连】。如果恰有一个,那么这个点就是newroot
, 如果没有,那我们就枚举newroot
。
对于一组已知的LCAlca(a,b)=c
- 如果
c=root
,a,b
都在newmask
中,不合法。 - 如果
c
在newmask
中,a,b
有一个不在newmask
中就GG了。因为这样的话,c
在newmask
对应的子树里面,a,b
至少有一个在newmask
子树外面。
对于合法的newroot
,newmask
\(dp[mask][root] = \sum dp[newmask][newroot]*dp[mask-newmask][root]\)