今天有点小失误,但是总体还行。
T1:首先70分的O(n)dp很容易推出来:
设f[i][0/1]表示长度为i的区间的根节点是否有选的最大匹配数,g[i][0/1]表示方案数。分类讨论转移即可。
100分就是把用递归来实现dp,并且有哈希来记忆化。可以证明总的区间长度种数是logn级别的(还是要分类讨论)。
总结:比赛时就算想不出正解也不要忘记打个水法来水分。
T2:首先进行长链剖分(其实就是把拥有深度最大的叶子的儿子作为重儿子),显然选择长度前l大的长链是最优的。
接着我们可以从小到大枚举d,一层一层地加点,用一个桶来维护前l大的和。
至于用桶怎么来维护,这个不好讲,但是我们可以抓住每次只将一个值加1来更新分界线。贴一下代码:
int p1(int x)
{
if(x>0)cnt[x]--;
cnt[x+1]++;
if(x>=di)v++;
if(x==di-1||di==0&&x==0)s++;
while(s-cnt[di]>=l){s=s-cnt[di];di++;}
}
T3:题解待更新。