CEOI2020 做题记录
D1T1 「CEOI2020」花式围栏
简单题,直接按高度排序从大往小加
写个并查集维护连续段来统计方案数
区间合并就把左右端点在两边的,高度在当前高度内的答案加上即可
D1T2 「CEOI2020」道路
填坑。。。
先把所有的线段旋转一个角度避免线段没有斜率的情况
考虑扫描线
用一根平行于y轴的扫描线从左往右扫,并动态构建这棵树
开一个set动态维护与当前扫描线有交的所有线段的大小顺序
一条线段加进去的时候我们考虑给他的左端点连接一个点加入这棵树
于是我们考虑他在set里的前驱
但是这个前驱的左端点不一定满足要求,可能连线是有交的
但是我们对于set里的每一个点,记录他下面最后一个加入或者删除的点就可以满足要求了
具体见代码
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)\)