D1T1 「CEOI2020」花式围栏
简单题,直接按高度排序从大往小加
写个并查集维护连续段来统计方案数
区间合并就把左右端点在两边的,高度在当前高度内的答案加上即可
D1T3 「CEOI2020」星际迷航
一道题做4天不愧是我
首先考虑(D=1)怎么做
首先容易发现每一个点不是必胜就是必败
于是我们可以换根dp出每个点的胜负状态
我们发现其实我们如果把宇宙(1)里的一个必胜点连到宇宙(0)里对宇宙(0)的胜负状态是不影响的
如果连的是一个必败点那么就是把宇宙(0)里的一个点变成了必胜点
我们再dp求出改变这个节点的胜负状态为必胜后,能使(1)号节点的状态变为必胜的节点的个数(cnt)
那么答案就是(W*n*win_1+L*cnt)
其中(W)表示原图中必胜点的个数,(L)表示必败点的个数,(win_1)表示(1)号点是否必胜
如果你的所有dp都是(O(n))的话就做完了
现在我们考虑(D>1)的情况
我们发现(W)和(L)变成了对于(t in [1,D])的宇宙间所有的连边方案,在宇宙(1)里的必胜点个数之和和必败点个数之和
我们考虑dp求出这个东西
我们求出钦定每一个点必胜,原图中必胜点的个数和(A),和原图中必败点的个数和(B)
我们认为原图中必胜点个数是(W_1)
于是我们不难发现
(W_D=W_{D-1}*W_1*n+L_{D-1}*A)
(L_D=W_{D-1}*L_1*n+L_{D-1}*B)
其实就是考虑在最前面加一个宇宙,然后考虑连边是必胜点连过去还是必败点连过去
我们发现这可以矩阵乘法优化
所以就(O(n+logD))了
那么(A)和(B)怎么算呢
我的方法很暴躁,大家可以去看下Itst的方法非常简洁但是我没看懂
简单介绍下我的nt做法
记(g[x][0/1])表示从x点的父亲节点出发,只向(x)的子树外走,状态为必胜/必败时,在(x)子树内的必胜点个数
从下向上dp转移
转移比较简单就不写了,如果大家有兴趣可以去看我的代码
记(h[x][0/1])表示从x点出发,只向(x)的子树内走,状态为必败/必胜时,在(x)子树外(含x)的必胜点个数
从上到下dp,换根转移,讨论很麻烦,如果大家有兴趣可以去看我的代码
那么对于钦定x点是必胜点的情况下,必胜点个数就是(g[x][1]+h[x][1]-1)
那么就可以做了
D2T1 「CEOI2020」权力药水
观察到卡空间,所以空间复杂度(O(nd))的简单做法不可行
我们考虑一个类似于线段树分治的做法
对于每一条边可以简单求出他作用的时间区间
对于每一个点以时间为下标用动态开点线段树套vector存一下每一个时间的信息
使用类似于标记永久化的技巧
询问就在线段树上暴力把时间点对应的所有点拿下来即可
然后排序双指针回答询问
时间复杂度是(O(ulogu+qdlogd))
在loj上空间卡过去了在洛谷上mle了
D2T2 「CEOI2020」春季大扫除
首先加入叶子以后总叶子个数是奇数显然无解
我们考虑把一个非叶子节点提成根
对于不是根的节点,我们贪心地考虑,一个点子树内的叶子显然要尽量多配对
对于所有儿子节点里的叶子,我们考虑两两配对
但是这个点到父亲的边需要被覆盖
那么如果这个点子树内有奇数个叶子,则只需要随意留一个叶子即可,否则需要留两个叶子
把留下的叶子传到父亲节点去
容易发现这样恰好可以配对,并且总答案最小
接下来计算答案
我们考虑如果一个点子树内有奇数个叶子,那么他到父亲节点的边会被覆盖一次,否则会被覆盖两次
那么答案就是
(n-1+sum_{i!=rt}[i的子树内有偶数个叶子])
考虑每次怎么计算,容易发现只需要虚树上dp即可
时间复杂度(O(nlogn))