Walking Seasons 冰与火之舞自制谱
这是我制作的《冰与火之舞》(A Dance of Fire and Ice)自制谱,使用的歌曲是 COP 的《walking seasons》。
压缩包中包含谱面文件、封面图和歌曲音频。下载后解压,并从《冰与火之舞》的自定义关卡界面载入 level.adofai。
这是我制作的《冰与火之舞》(A Dance of Fire and Ice)自制谱,使用的歌曲是 COP 的《walking seasons》。
压缩包中包含谱面文件、封面图和歌曲音频。下载后解压,并从《冰与火之舞》的自定义关卡界面载入 level.adofai。
本文迁移自洛谷原文。
模拟赛考了这题,花了2h刚了个弱智的点分治做法。
假设当前我们分治到的重心是
这时候就会有两种情况:
那么我们可以对
排序后,由于可能存在多个直径,我们需要找到所有经过点
证明:
如果有多个儿子的深度最大,那么该方法肯定只在他们之间选。而且,根据第二关键字,我们选前两个就足以凑到在公共部分最长的情况下总长度最长的 方案了。
如果只有一个儿子深度最大,那么按照第二关键字还是能把所有深度第二大的儿子按照分叉从大到小排序,仍然可以选择前两大的配对。
这种情况可能在一个蒲公英一样的图上出现(一个菊花接了一条链和一个小分叉)。
那么
然后套一个点分治模板就行了。
1 | #include<bits/stdc++.h> |
本文迁移自洛谷原文。
CF372C Watching Fireworks is Fun
我们可以换种思考方式来解决这个问题。
显然
令
假设我们已经考虑了前
令
然后每燃放一场烟花,我们就相当于对
综上,可以发现,这个
考虑继续优化。
发现这个
这启发我们可以维护两个优先队列一样的东西,一个维护左半段斜率小于
我们考虑在这种维护方式下,等待时间和加入烟花秀各有什么影响。
由于这个
当然,我们没有必要真的去减一遍,我们只需要维护两个全局减去/加上的
再考虑这个加入烟花的操作。
令左半段最右边的转折点横坐标为
此时就相当于
此时
所以我们加入两边
和上一种情况同理。
综上,时间复杂度
Code:
1 | #include<bits/stdc++.h> |
本文迁移自洛谷原文。
这里是 [CSP-S 2022]假期计划 的另类做法。
先暴力bfs把所有能在
然后随机染色。对于每个点,随机染上
显然这是原问题的弱化版,每次有
1 | //start coding at 2:35 |
upd:这份没有卡时的代码在官方数据下获得了整整 65pts,但我们可以通过一个 clock() 来进行卡时,获得 100pts。
Code:
1 | #include<bits/stdc++.h> |
本文迁移自洛谷原文。
题目意思很清楚不解释。
我们一共有
稍微思考一下即可发现,这个题目等价于保留代价最大的那些链,然后删掉剩余的边进行缝缝补补。(因为最后是要变为一个环,换上每个点的入读和出度均为
回头看看这个图。
对于一个树点,由于要删掉大部分边使得它的入度变为
由于这张图可能是个基环树森林,我们需要把所有的环也拼接起来,所以说,每个环上至少要断开一个点。
对于一个环,我们令
统计
如果这个环的
如果这个环的
ps. 有一个特例,整张图只有一个大环,且这个大环包括了所有点的时候,它既不需要和其他环拼接,也不需要让其他树点挤进来,所以答案就是
Code:
1 | #include<bits/stdc++.h> |
本文迁移自洛谷原文。
题目意思很清楚不用说。
看到每个点都有颜色,然后询问和颜色的种类有关,时限开了很【】的 8s,就可以往根号分治方面想了。
按照常理,我们钦定一个
如果
如果
同理,如果
最后,如果
上述全部为口胡,如果实现不精细的话,时间复杂度会写成
普通的倍增LCA的询问是
在建立虚树的时候,有一步要对所有点按照 dfs 序排序。如果不想写基数排序怎么办?可以在询问前先对每个
现在的时间复杂度已经降到了正好的
为了减小常数:
加入快读快输
小对小和大对大中暴力统计答案的dfs看起来很累赘,那么短。如果我们能够想办法把这一步放入建立虚树的过程中,那么就可以避免存虚树的边,从而大幅减小常数(感谢 w23c3c3 的指导)
然后这样就能过了。
Talk is cheap, show me the code.
1 | #include<bits/stdc++.h> |
本文迁移自洛谷原文。
上架建议:套路模板题,蓝。
z
我们把这个平面可以旋转
也就是说,原来是一个斜着的正方形求和,现在变成了水平的了,直接用前缀和即可。
原来:
旋转后:
实现有点丑陋,仅供参考。
1 | #include<bits/stdc++.h> |
本文迁移自洛谷原文。

单调性可以被感性发现。
但是我们要注意一点,就是“在碰到一个人之后立刻点燃烟花棒”是不优的。
显然,我们可以让上一个人一直跟着这个人跑,直到烟花棒耗完。同样,无论在耗完的路上遇到了多少人,他们都可以一起跑。可以发现,我们这么做,即等到它耗尽再传递,能够延长火种运输的时间。因为你不用考虑这些人是否会累死
然后我们贪心的考虑,肯定是
如果一些人一直同向跑的话,那么他们之间的距离不会变。所以说,在这个过程中,只有
所以,这道题就可以转化成有两列人,每次一个一个撞掉开头的一个,会消耗一定的时间,如果撞掉了就可以获得
考虑把前面的人和后面的人都分成一些连续的小段,满足每个段的所有前缀都满足
如果这两列能够正好被分为一些小段,那么我们执行以下操作:
每次选择一个段然后撞完,如果不能撞则一定不行了。
证明:
如果你没有把一个段撞完就去撞另外一个段,那么你肯定不如不撞这个段直接去撞另外一个段来的优,毕竟我们这个“段”的定义是所有前缀的前缀和都是要亏本的。
那么撞段的顺序会不会影响呢?也是不会的,因为这个段同时还满足了总的是要赚时间的,所以撞完就一定会有盈利。假设你面对的是两个段,你都能撞完,那么你先撞完第一个是肯定能撞完第二个的,先撞第二个同理。
综上,这个贪心策略是可行的。
如果不能被正好分完,那么就可以发现这个后缀满足
感性证明的时候感觉会可能出现还需要再翻转再递归求下去的情况,但其实不会。因为如果出现了,那么我们可以吧这个后缀提出来,发现是满足
Talk is cheap, show me the code.
1 | #include<bits/stdc++.h> |