【杂题乱写】Codeforces Round#905

由于是解题报告不是过题报告,所以理所当然的放弃了后三题代码的写。

感觉这场 Div1 D 是 cyh 的菜,E 是 gjk 的菜。我负责菜。

只写 Div1 题的题解。

A

双指针可以做 m=1

你发现随便换 a1 答案最多减少 1,而且 a1 越趋向于减少,所以可以二分分割点

B

最短路,怎么 dijkstra 呢?设 disx 表示到达 x 号节点的时间(在传送机序列上)

那么把每张图在序列上什么时候出现记下来,每条出边直接二分找大于 disx 的最小的就行啦。

C

原序列字典序最小和最小化差分数组字典序没什么区别。考虑进行修改 1i 和进行修改 1j 哪个得到的序列会字典序更小一些。(i<j

这其实就是看修改 i+1j 对原序列的影响,如果第一个非零的位置是负数,后者就要更优。所以搞一个 std::map 这些单点修改造成的影响存下来,随时把前缀的 0 赶出去就可以得到哪个修改的前缀最好,然后模拟一下得到答案。

standings 上一堆线段树,笑死我了。

D

注意到 a 是一个排列,那么根据常见套路,设置一个阈值 x,大于 x 的看成 1,否则是 0

如果一个区间只有一个 01 的分界线,那么这个区间是合法的。不难发现伴随着阈值的增大,每个数都会从 01 变化一次,每个数变化的时候这个 01 序列的其他部分不变,可以使用 std::multiset 找到前面最靠后的的 1 和后面最靠前的 0。中间这一坨就是可行的询问区间,那么变成了矩形加,单点判断 0/1。

这就是大家都知道的树状数组问题啦。

E

不难发现这就是个二分图(每行当成点,每列当成点)。因为上来给了你 2n 条边,所以你一定可以找到一个长度为偶数的环

其实你发现你最终的目的是找到一个颜色互不相同的四元环。所以做法就是你在这个环上找两个点求问它们之间的边的颜色是啥,从这两个点中间把这个环拆开成左右两部分,因为一开始的边的颜色互不相同,所以如果这条新边哪边都不一样就递归这边当成子问题。

你发现找的两个点的距离是二分之环长能让递归的次数最少,正好 210=10241000

F

考虑构造一个 nxt 数组,nxti 表示下一个和 ai 一样的数的位置,如果求出来 nxti,相当于得到了若干链,每条链给一个数值就行了。

不难发现:

  • nxtn=n+1
  • 如果 ri=ri+1 那么 nxti[i+1,ri]
  • 如果 ri<ri+1 那么 nxti=ri+1

利用上面三条我们可以得到一些点值和一些区间

  • 如果 nxtin 那么这些 nxti 互不相同。
  • 对于 i>nxt1 都有 j<i 满足 nxtj=i

最后一条限制如果被忽略的话,那么通过贪心给 nxti 赋值,赋不了的全都干成 n+1

如果我们需要考虑最后一条限制,可以考虑枚举有多少个 nxti 选择了 n+1。不难发现对于确定的 k 选最靠右(右端点)的区间选择 n+1 一定不劣,剩下的元素仍然是依次贪心。

k 显然具有可二分性,找到最小的满足条件的 k 进行 nxt 的构造即可。jiangly好像有一个不用二分的代码,不知道做法是啥。可能是继续 optimize

posted @   没学完四大礼包不改名  阅读(140)  评论(11编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示