耻辱柱一号
这里记录了 2023.11.26-2023.12.29 期间打的共 32 场 CF 比赛。
但是仍然有很多没写总结,比如第二场到第七场,以及最后的两场「baoyang vs qcf」。先咕着,有空写。
Part 0.场内切题数量统计
第一场「CF1845,Round151」
切三题,ABC。
第二场「CF1841,Round150」
\(\color{red}切两题,AB。\)
原因:
C:自己写的代码又臭又长,场内切不出来有很大原因是思路想复杂(虽然也能做)导致代码也复杂。
D:补了好久好久,怎么也没想到能把每两条相交的线段合并为一条线段,在转化为一个贪心:按右端点排序,按顺序枚举,能要就要。
E:栈好题,画画图做出来。
总结:三个题里做题时间最短的就是E题,但做题时长是否超出了比赛内的空余时间,我记不得了。
第三场「CF1697,Round130」
\(\color{red}切三题,ABC。(D题赛后5分钟切出来啊啊啊啊啊啊啊!!!)\)
第四场「CF1681,Round129」
\(\color{red}切两题,AB。\)
C:自己写的代码又臭又长,而且打这一场的时候只有一个半小时(当然时间够用的话也切不出来)。还是思路复杂,如果把a和b合并一下,cmp改成两个数的a相等时按照b排序,遍历一遍b是否有序其实就好了,输出方案的话就记录一下idx直接打印不就行了么,非要写的那么复杂
D:搜索,感觉场内应该能切出来但就是一直在做C题,就没去做
E:坏倍增,调了好久,场内绝对切不出来。
总结:还是应该看一遍题,找到哪个最简单去做哪个,不能在一个题上死磕
第五场「CF1709,Round132」
\(\color{red}切两题,AB。\)
C:直到赛后也没想出来,问了qcf,把问题转化后仍然没做出来,看了题解的逆天做法后写了写过了,但仍然看不懂。
感觉那个把前L个填成 \((\) ,把后R个填成 \()\) 的做法才是人能理解的
D:纯纯的水题
E:不会dsu on tree,问了cy才会。
总结:仍然是没看好难度,如果直接做D的话肯定能做出来,偏偏去做那个该死的C题,然后还做不出来。
第六场「CF1701,Round131」
切三题,ABC。
第七场「CF1716,Round133」
\(\color{red}切两题,AB。\)
C:不仅是场内切不出来,补题时也在想一个倍增,结果数组大小应该是3,开成2导致TLE,一直改不出来都要爆炸了,没想到完全可以不用倍增,在正解中发现了TLE原因,才把两种做法都过去,太逆天了!!!
D:他么的一个类似单调队列优化多重背包的,把余数相同的状态做前缀和优化dp都想不出来,脑子不知道在干什么
E:没想到状态数很少,明明搜一遍就能出来的……
总结:三个题罪大恶极,做的时间一个比一个长,场内切不出来是脑子裂开了导致的
第八场「CF1832,Round148」
切三题,ABC。
第九场「CF1680,Round128」
切三题,ABC。
第十场「CF1849,Round152」
切四题,ABCD。
第十一场「CF1861,Round154」
\(\color{red}切两题,AB。\)
C:一开始读错了题,题读对了之后开始做,想得太简单了,以至于一直错,发现稍微冷静一下应该就能找到做法,偏偏就没找到……
D:dp,补题的时候都做了好久,别提场内了
E:逆天题和逆天结论和逆天猜结论人
总结:补题时间都极长,感觉场内做不出来一是急了,二是真的做不出来
第十二场「CF1860,Round153」
切三题,ABC。
第十三场「CF1837,Round149」
切四题,ABCD(或者说4.5,因为场后马上切出了E)。
第十四场「CF1821,Round147」
切四题,ABCE。
第十五场「CF1792,Round142」
\(\color{red}切两题,AB。\)
C:咋也没想到二分,硬是在那里想想想,想不出来。
D:好题,好分治,如果场内做的话大概率做得出来
E:逆天题,因数个数我和你拼了!!!
总结:急了,C想不出来纯粹是急了;难度分配不合理,应该做D再做C
第十六场「CF1783,Round141」
\(\color{red}切两题,AB。\)
C:杀杀杀,场后补题还是杀杀杀,写的极为复杂……
D:简单dp。
E:就在写这个剪贴板的前一天才做出来,记忆犹新,整除分块过不去,正解还想不到,很离谱。
总结:应该先做D题
第十七场「CF1882,Codeforces Round 899」
切三题,ABC
第十八场「CF1739,Round136」
切三题,ABC。
第十九场「CF1721,Round134」
切四题,ABCD。
第二十场「CF1661,Round126」
\(\color{red}切两题,AB。\)
C:逆天提,分讨讨论不出来,还浪费时间硬想。
D:简单枚举
E:还没做
总结:应该先做D题。
第二十一场「CF1814,Round146」
切三题,ABC。
第二十二场「CF1809,Round145」
\(\color{red}切三题,ABC。(D题赛后5分钟切出来啊啊啊啊啊啊啊!!!)\)
原因:跑神了!!!你在干什么啊!!!!!!!!
第二十三场「CF1796,Round144」
\(\color{red}切三题,ABC。(D题赛后3分钟切出来啊啊啊啊啊啊啊!!!)\)
原因:单纯时间不够用啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!!!!!!!!!!!!!!!!!!!
\(\color{gold}第二十四场「CF1795,Round143」\)
\(\color{gold}切五题,ABCDE。\)
第二十五场「CF1767,Round140」
切三题,ABD。
第二十六场「CF1766,Round139」
切三题,ABC。
第二十七场「CF1749,Round138」
切四题,ABCD。
第二十八场「CF1743,Round137」
切四题,ABCD。
第二十九场「CF1728,Round135」
\(\color{red}切 3.\dot{9} 题\),\(\color{black}ABC \color{grey}D\)。(\(\color{red}D题闹钟响后五秒钟交上去过了\))\(\color{white}切四题\)
\(\color{gold}第三十场「CF1671,Round127」\)
\(\color{gold}切五题,ABCDE。(这一场也太水了吧……)\)
第三十一场「baoyang vs qcf round 1」
切三题,ABD。
C题纯纯大水题为什么不做啊啊啊啊!!!被qcf生吃了!!!
第三十二场「baoyang vs qcf round 2」
切两题,AB
孬坛B题,逆天构造,被狠狠地诈骗。
为什么C题的st表寄掉了啊啊啊啊啊啊啊啊!!!
Part 1.第一场~第十场
第一场-CF1845
超级大分讨,慢慢分类慢慢做就出来了。
仍然是分讨,慢慢分类慢慢做就出来了。
记 \(dp[i][k]\) 表示从 \(i\) 开始到 \(n\),\(s\) 中第一个出现 \(k\) 的位置。
然后从 \(1\) 开始往前跳就行了。
咕咕咕咕咕咕咕咕
咕咕咕咕咕咕咕咕
第二场-CF1841-第七场
第八场-CF1832
如果原串从第 \(1\) 个位置到第 \(\frac{n}{2}\) 个位置 由同一个字符组成就不行,否则就可以,枚举一下就行。
排个序,算个前缀和,枚举 \(k\) 次操作是由几次操作一和操作二,直接统计答案。
- Contrast Value CF1832C \(\color{red} 耻辱!\)
把序列 \(a\) 划分为连续的上升段和下降段,在每个段端点上放一个数,放的数的数量就是 \(b\) 的最短长度。
当时做的时候连如何把序列划分成上述的段都不会写了。
代码底力和基本功还是太低了!还是得多练练!菜就多练练!
- Red-Blue Operations (Easy Version) CF1832D1 && (Hard Version) CF1832D2 \(\color{red} 耻辱!\)
思考时间过长+冷宫常住人口。
非常好题目,爱来自河的南方。
想了好久原问题,不会做;试了试 \(k=1\) ,发现好做;试了试 \(k=2\) ,发现不会做;摆烂去打球了。
回来之后试了试,通过考虑 \(n\) 的奇偶性,划分成 2 个序列,分配一堆 -1 就做出了 \(k=2\) ;
然后又试了试 \(k=3\) ,逐渐发现这东西好像和 \(k\) 的奇偶性相关。
于是就试了 \(k\) 为奇/偶的做法,没想到真的成了!(虽然是 \(O(nq)\) ,只能过 easy version )。
具体地说,先把 \(a\) 数组排个序。
若 \(n \le k\),就把 \(n \sim 1\) 这些数分别加给 \(a_{1 \sim n}\) 身上就行了。
若 \(n > k\),当 \(n\) 和 \(k\) 同奇偶时,就把 \(k \sim k-n+1\) 这些数分别加给 \(a_{1 \sim n}\) 身上;不同奇偶时,就把 \(k \sim k-n+1\) 这些数分别加给 \(a_{1 \sim n-1}\) 身上。
此时 \(1 \sim k\) 剩下的数的数量肯定是偶数,\(1\) 和 \(2\),\(3\) 和 \(4\) ……两两分组,每一组都是一个 \(-1\) ,记此时 \(-1\) 的个数为 \(tot\)
若此时 \(del=\sum\limits_{i=1}^n (a_i - a_{min})\) \(\ge tot\),则答案就是 \(a_{min}\)。
否则就把 \(tot-del\) 个 \(-1\) 平均分配一下,最小值就是答案
然后试着优化,提前预处理出 \(b_i = a_i + (n-i+1)\) ,\(mqian_i = \min\limits_{j=1}^{i} b_j\) , \(mhou_i = \min\limits_{j=i}^{n} a_i\),
就可以做成 \(O(n+q)\) 了!然后就爽做了hard version。
- Combinatorics Problem
CF1832E \(\color{red} 耻辱!\)
思考时间过长+冷宫常住人口
非常不好评价的组合数dp,借助了蓝书上的一个递推式做出来的
\(C(n,m)=C(n-1,m)+C(n-1,m-1)\)
然后记 \(dp[i][j]\) 为 \(b[i]\) 在 \(k\) 为 \(j\) 时的取值,那么 \(dp[i][j] = dp[i-1][j] + dp[i-1][j-1]\)。
然后就做完了。
第九场-CF1680
区间相交就是相交处的最左端,不交就是 \(l_1+l_2\)。
找到一个最小的矩形,能够包围所有的机器人,若该矩形的左上角是机器人就 YES,否则就NO。
- Binary String CF1680C \(\color{red} 耻辱!\)
先把字符串最前面和最后面的 \(0\) 删掉,显然是好的。
把剩余的部分看做连续的 \(1\) 段 和连续的 \(0\) 段,枚举左边删掉多少对 \(1\) 段和 \(0\) 段,并二分右边删掉多少个段,统计答案就行。
耻辱原因是写得太复杂了,以至于自己本人隔几天就看不懂了。
- Dog Walking CF1680D \(\color{red} 耻辱!\)
思考时间过长+冷宫常住人口+未补
- Moving Chips CF1680E \(\color{red} 耻辱!\)
思考时间过长。
又是传奇场,耻辱柱三连。
考虑了一个贪心,然后测了几组没毛病,交了,挂了,测试点输出来发现假了。
然后开始考虑一个dp,考虑了一个 \(dp[i][0/1]\) 表示在 \(i\) 这个位置有没有进行一次「收割」。
所谓收割就是从某个 \(j(j<i)\) 开始,先向下走一格,在往右走走到 \(i\) 的下方,在上去到 \(i\) 。
然后就分别让第一行和第二行在上,然后跑一遍这个dp(转移式极其抽象,有一群魔术数字,不写出来了)。
很抽象地过去了。
第十场-CF1849
如果 \(b-1\le c+h\),则意味着所有的面包都能用,夹心用不完,答案是 \(2\times b-1\)。
否则的话所有夹心都能用,面包用不完,输出 \(2\times (c+h)+1\)。
当可以开始杀死某一只怪物时,所有的怪物肯定都已经残血了(能一刀秒),那就把所有怪物的血量 模 \(k\) 后的值(整除 \(k\) 时这个值是 \(k\))和怪物编号扔进结构体排个序,依次输出编号就行了。
字符串哈希,用 set 存哈希值,这个题只用 \(131\) 或 \(13331\) 中某一个来单哈希都不行,所以双管齐下双哈希就行了。
- Array Painting CF1849D \(\color{red} 耻辱!\)
好像并不是很耻辱,但思考时间不短
做法就是找到好几个有数的段,对于每个段:
存在2就意味着该段染一下后两边的0都能染
不存在2就意味着该段只能然左右两个0之一
然后从左往右贪心地往左染就行了
- Max to the Right of Min CF1849E \(\color{red} 耻辱!\)
思考时间过长
乱用启发式合并发现需要写八个二分,后来想了想发现只要四个二分,但是太逆天了!不会写!
于是想到了一个线段树的做法:枚举一个 \(1\le i\le n\),记当前枚举到了 \(i\)。
我们维护一个数组 \(c\),\(c_j=1\) 表示区间 \([j,i]\) 是个符合题意的区间,为 \(0\) 表示该区间不符合题意。假设此时我们已经计算出了 \(c_1 \sim c_{i-1}\)。
考虑 \(a_i\) 会对 \(c\) 数组产生什么样的影响,以及如何统计答案。
先考虑 \(a_i\) 可以作为以 \(pos+1\le j < i\)为左端点,\(i\) 为右端点的这些区间的\(\color{blue}最小值\)。这里 \(pos\) 为某一个分界点,以 \(1\sim pos\) 为左端点,\(i\) 为右端点的区间都不以 \(a_i\) 为最小值(\(pos\) 不存在则为 \(0\))。
考虑 \(a_i\) 作为区间最小值的这种区间存在的充要条件:当且仅当 \(a_{i-1}\; {\color{blue}>}\;a_i\) 时,这种区间存在。
经过一番思考可以发现 \(pos\) 是 \(i\) 之前 第一个 \(a_{pos} \; {\color{blue}<}\; a_i\) 的位置,所以 \(pos\) 可以用单调栈维护。
对于以 \(1\sim pos\) 为左端点,\(i\) 为右端点的区间,由于不以 \(a_i\) 为\(\color{blue}最小值\),所以 $a_i $ 对其无影响,可以直接给答案加上 \(\sum\limits_{j=1}^{pos}c_j\);
而对于 以 \(pos+1\le j < i\)为左端点,\(i\) 为右端点的这些区间,由于它们都以 \(a_i\) 为区间\(\color{blue}最小值\)了,故这些区间都不能满足 题中的条件,所以令 \(c_j \gets 0 \Big(pos+1\le j <i\Big)\)。
再考虑 \(a_i\) 可以作为以 \(pos+1\le j < i\)为左端点,\(i\) 为右端点的这些区间的\(\color{blue}最大值\)。这里 \(pos\) 为某一个分界点,以 \(1\sim pos\) 为左端点,\(i\) 为右端点的区间都不以 \(a_i\) 为最大值(\(pos\) 不存在则为 \(0\))。
考虑 \(a_i\) 作为区间最大值的这种区间存在的充要条件:当且仅当 \(a_{i-1}\; {\color{blue}<}\;a_i\) 时,这种区间存在。
经过一番思考可以发现 \(pos\) 是 \(i\) 之前 第一个 \(a_{pos} \; {\color{blue}>}\; a_i\) 的位置,所以 \(pos\) 可以用单调栈维护。
对于以 \(1\sim pos\) 为左端点,\(i\) 为右端点的区间,由于不以 \(a_i\) 为\(\color{blue}最大值\),所以 $a_i $ 对其无影响,可以直接给答案加上 \(\sum\limits_{j=1}^{pos}c_j\);
而对于 以 \(pos+1\le j < i\)为左端点,\(i\) 为右端点的这些区间,由于它们都以 \(a_i\) 为区间\(\color{blue}最大值\)了,故这些区间都能满足 题中的条件,所以令 \(c_j \gets 1 \Big(pos+1\le j <i\Big)\),并让答案累加 \(i-pos-1\)。
经过以上讨论,发现 \(c\) 数组需要支持如下操作:区间求和、区间赋值。可以用线段树来维护数组 \(c\),然后这个题就华丽地解决了!
part 2.第十一场~第二十场
第十一场-CF1861
\(79\) 和 \(97\) 都是质数,而且两者必定出现其中之一。
所以判断一下 \(7\) 和 \(9\) 的前后关系,直接输出即可。
(以上做法是伟大的 Qcf 告诉我的,我是把所有两位质数存进 map,枚举两个位置做的)
如果存在一个位置 \(1\le i <n\),满足 \(\begin{cases}s1[i]=0,s1[i+1]=1\\s2[i]=0,s2[i+1]=1\end{cases}\),则输出 YES,否则输出 NO。
- Queries for the Array CF1861C \(\color{red} 耻辱!\)
场内切不出来真的是太孬坛了。
读错题了,以为是1升序0降序,做了好久好久,发现死掉了。
一定要读准题啊!读明白了再做题!!!!!
不难发现序列一定是由一段有序段和一段无序段拼起来,于是用两个变量记录一下有序段和无序段的位置,一通模拟即可(不展开写了,因为写这篇博客时已经看不懂我写的代码了)。
- Sorting By Multiplication CF1861D \(\color{red} 耻辱!\)
思考时间过长
仍然是晚上读错题了,以为x>=0,想了一个早读的假做法,结果一会机房发现消愁了
记 \(dp[i][j]\) 为第 \(i\) 位 \(\Bigg(\begin{cases}j=0 &\text{不使用操作}\\j=1 &\text{乘上一个绝对值很大的正数}\\j=2 &\text{乘上一个绝对值很小的正数}\\\end{cases}\Bigg)\) 的最小操作数。
考虑转移:
\(\begin{cases} {\begin{cases}dp[i][0]=min(dp[i-1][0],dp[i-1][2])\\ dp[i][2]=1+dp[i-1][2]\\ dp[i][1]=min(dp[i-1][0] , dp[i-1][1] , dp[i-1][2] )\end{cases}} &a_i>a_{i-1}\\ {\begin{cases}dp[i][0]=dp[i-1][2]\\ dp[i][2]=dp[i-1][2]\\ dp[i][1]=1+min(dp[i-1][0] , dp[i-1][1] , dp[i-1][2] )\end{cases}} &a_i<a_{i-1}\\ {\begin{cases}dp[i][0]=dp[i-1][2]\\ dp[i][2]=1+dp[i-1][2]\\ dp[i][1]=1+min(dp[i-1][0] , dp[i-1][1] , dp[i-1][2] )\end{cases}} &a_i=a_{i-1}\\ \end{cases}\)
不方便慢慢解释了,而且这个状态本身就很迷惑,这个转移式也很迷惑……
- Non-Intersecting Subpermutations CF1861E \(\color{red} 耻辱!\)
思考时间过长+冷宫常住人口
神了这场比赛,CDE都被我钉在耻辱柱上
考虑了 \(dp[i][j]\) 表示长度为 \(i\),价值为 \(j\) 的方案数,统计答案
\(ans=\sum\limits_{j=1}^k dp[n][j] \times j\)
结果寄掉了,连 \(dp[i][0]\) 都不会算
后来思考了好久,发现了一个好玩的东西:当一个串贡献为 \(j\) 时,可以把这 \(j\) 个贡献拆开来计算,
于是考虑 \(dp[i]\) 为刚好有一个长度为 \(k\) 的贡献处于 \(i-k+1 \sim i\) 时的方案个数。
首先 \(dp[i]=0\;\big(1\le i < k\big)\),\(dp[k]=k!\) 毋庸置疑。
对于 \(dp[i]\;\big(k< i \le n\big)\),在 \(i-k+1 \sim i\) 处填一个 \(k\) 的排列的方案数,是 \(k!\),而剩余的 \(i-k\) 个位置的填法数量为 \((i-k)^k\)。
考虑有哪些重复的可能性,令 \(1 \le j <k\),显然只有在 \(i-j\) 处,往左填一个排列的情况会被重复计算。
所以对于每个 \(j\),\(dp[i]\) 要再减去一个 \(dp[i-j] \times j!\) 。
这里解释一下为什么要多乘一个 \(j!\;\):当以 \(j\) 为结尾的这个排列确定为 \(dp[j]\) 中的某一种之后,\(i-j+1 \sim i\) 这些数的填法有 \(j!\) 种填法,所以要乘一个 \(j!\;\)。
这里列一下总转移式:\(\;dp[i] _ {(k< i \le n)} =k!\times(i-k)^k-\sum\limits_{j=1}^{k-1}(dp[j]\times j!)\)
第十二场-CF1860
如果 \(s\) 不是 \(()()()()()()\)……的一个子串,就输出 \(n\) 个「\(()\)」。
否则就输出 \(n\) 个「\((\)」和 \(n\) 个「\()\)」。
大分讨,不展开写了,太难受了。
对于第 \(i\) 个位置来说,如果前面不存在比 \(a_i\) 小的点,或存在一个小于 \(a_i\) 的必胜点,那这里就是必败点,否则是必胜点。
我们把必胜点记为 \(1\),必败点记为 \(0\),发现我们一共要维护两个东西:当前比 \(a_i\) 小的数、当前比 \(a_i\) 小的必胜点个数。
所以我们在值域上建两颗树状数组,直接维护就行了。
- Balanced String [CF1860D] \(\color{red} 耻辱!\)
思考时间过长+冷宫常住人口+未补
- Fast Travel Text Editor [CF1860E] \(\color{red} 耻辱!\)
思考时间过长+冷宫常住人口+未补
第十三场-CF1837
如果 \(x \bmod k \not=0\),就一步跳到 \(n\);否则先跳一步再跳 \(n-1\) 步。
把 \(s\) 分成连续的 \(<\) 和连续的 \(>\),输出最大段长 \(+1\)。
如果 \(s_1=?\),则 \(s_1=0\);如果 \(s_i=?\),则 \(s_i=s_{i-1}\);
如果原序列本身合法或逆合法,就输出 \(1\)。
否则一定能把原序列分成两部分,一部分是正合法,另一部分是逆合法。
染个色标记一下就行了。
假设当前是第 \(i_{(1\le i \le k)}\) 轮,则这一轮淘汰的必须是 \(2^{k-i}+1 \sim 2^{k-i+1}\) 这些队伍。
考虑当前内定的会不会使它们之间互相争斗,以判断无解。
把这一轮还没有被内定的这些人填进去,答案累乘一下就OK了。
第十四场-CF1821
首位的 \(\tt{?}\) 贡献为 \(9\),其他的 \(\tt{?}\) 贡献为 \(10\)。
乘起来就好了。
先找到一对 \(l\) 和 \(r\),满足 \(a_{1\sim l} = b_{1\sim l}\) 且 \(a_{r \sim n} = b_{r \sim n}\)。
然后只要 \(b_l \ge b_{l-1}\),就把 \(l\) 减一,意味着多往左去一点参和进来排序没有问题;\(r\) 同理。
最后输出 \(l\) 和 \(r\) 即可。
枚举这个剩余的字符是谁(\(\tt{a}\sim \tt{z}+1\),\(\tt{z}+1\)意味着全都删),记为 \(c\)。
然后把原串分成几个交替的「由除了 \(c\) 的字符组成的段」和「只由 \(c\) 组成的段」。每次都从所有的「由除了 \(c\) 的字符组成的段」中各删一半,总操作次数就是 这些段长度的 \(\max\) 的 \(\log_2\)。
把所有的操作次数取 \(\min\) 即可。
- Black Cells CF1821D \(\color{red} 耻辱!\)
思考时间过长+冷宫常住人口+未补
先思考对于一个给定的字符串,怎么删会使代价最小。
可以分治地考虑:记原串是第 \(0\) 层。
假设当前是第 \(i\) 层,把串分成几个极小的合法段,从最右边的依次删起,删完这个合法段的代价就是:
$ \text{在深度为};i+1;\text{的基础上删完这个合法段的次数} + \frac{\text{这个合法段的长度}}{2} \times i$。
所以为了最小化代价,就要尽可能地使原串中,深度最大的合法段深度减小。
因为 \(k\) 很小,可以考虑直接枚举这 \(k\) 次操作。
每一次先找到一个最长的合法段,记为 \(l \sim r\),然后把处于 \(r\) 的右括号,移到处于 \(l\) 的左括号右边。
这样进行 \(k\) 次之后的串,代价最小。
第十五场-CF1792
排个序,不停地查看 \(a_1\) 是否为 \(1\),是的话就让 \(a_1\) 和 \(a_2\) 同时扣一滴血,然后序列整体前移,直到 \(a_1\) 不为1,剩余的怪物每一个都用一次操作直接杀死。这个过程中的操作次数输出即可。
第一类直接开演,演完了都是优的。
第二类和第三类可以交替着演,这样可以各演 \(\min(a_2,a_3)\) 场。
剩余的能演就演,演不了拉倒。
- Min Max Sort CF1792C \(\color{red} 耻辱!\)
纯纯的孬坛(指我自己),就是一个贪心+二分,咋就想不出来???
还被狠狠地诈骗,真的看不懂一个小时到底在想什么
做法:二分操作次数,假如当前二分值为 \(mid\),就进行 \(mid\) 次操作:第 \(i\) 次操作选取 \(mid-i+1\) 和 \(n-mid+i\),这样操作后序列会变成这个样子:
\([1,2,3...mid-1,mid,[\text{原序列中没有被选取的数,仍保持本来的相对位置}],n+1-mid,n+2-mid...n-2,n-1,n]\)。
此时看一下这个序列有没有序,有序的话 \(r=mid\),否则 \(r=mid-1\)。
- Divisors and Table CF1792E \(\color{red} 耻辱!\)
12.20一稿:
浪费了四个小时,罪大恶极。
原因是蓝书上的一句话:一个整数 \(N\) 的约数个数上界为 \(2\times \sqrt{n}\)。
所以我就觉得 \(1e18\) 的约数个数有 \(1e9\) ,想了一个晚上都没想出来,消愁消愁消愁消愁消愁消愁消愁消愁消愁消愁消愁消愁消愁消愁消愁消愁!
我甚至不对这个结论产生怀疑!!!!!甚至不去打个程序验证一下约数个数!!!!!!
12.21,AC后二稿:
早上想出正解了,以为错了就没写,看见qcf去问了,导致急了,马上就发现我想出来的是正解,飞快的写完了。
解法:既然知道约数个数只有 \(1e6\) 了,那就先把 \(m=m_1 \times m_2\) 的因数分解出来,方法是质因数分解 \(m_1\) 和 \(m_2\),然后枚举每个质因子的使用次数,深搜搜出来。
紧接着是一个极其巧妙的转换:把「最小行数」转化为「最大列数」,就方便进行 dp 转移了。
问题转化后就是:对于 \(m\) 的每一个因数,找到它在 \(n\) 以内的最大因数。把 \(m\) 的因数离散化,记 \(m\) 的因数个数为 \(tot\),记 \(dp[i]\) 为第 \(i_{(1\le i \le tot)}\) 个因数的最大列数(其实就是第 \(i\) 个因数的答案)。
初值:\(dp[1]=1\)。记 \(m\) 的不同质因子个数为 \(cnt\),\(p_{i_{(1\le i\le cnt)}}\)为 \(m\) 的第 \(i\) 个质因子。
形象地,把转移看做一个 DAG 图,对于一个因数 \(x\) ,设它有 \(cnt_x\) 个不同质因子,分别为 \(p_{tot,i_{(1\le i \le cnt_x)}}\),然后分别从 \(\frac{x}{p_i}\) 向 \(x\) 连一条边,代表着将来会从 \(\frac{x}{p_i}\) 向 \(x\) 进行一次转移。同时,\(x\) 的入度为 \(cnt_x\)(预处理)。
使用 bfs 进行转移:假设当前因数为 \(x\),枚举一下 \(i_{(1\le i\le cnt)}\),如果 \(x\times p_i \le m\),则考虑从 \(x\) 向 \(x\times p_i\) 进行一次转移。记 \(tmp=x\times p_i\)。
进行转移:\(dp[tmp]=\begin{cases}dp[tmp]\\dp[x]\\dp[x]\times p_i & dp[x]\times p_i \le n\end{cases}\)
同时,我们让 \(tmp\) 的入度减一,即 \(cnt_x\) 减一。如果减一之后 \(cnt_x=0\),则把 \(tmp\) 入队,向外转移。
突然意识到,其实我就是把有向图拓扑序遍历的过程说了一遍……
最后统计答案,对于 \(i_{(1 \le i \le tot)}\),若 \(\frac{m}{dp[i]} \le n\),则 \(ans1=ans1+1\),\(ans2=ans2 \oplus\frac{m}{dp[i]}\)。
第十六场-CF1783
先从大到小排序,找到存不存在一个 \(a_{pos}\not=a_1\),如果不存在就意味着所有元素相等,结果必定是丑陋的。
而但凡存在一个这样的 \(pos\),就可以把序列的前两项作为 \(a_1,a_{pos}\),剩余的就把排序后的序列依次输出就行。
- Matrix of Differences CF1783B \(\color{red} 耻辱!\)
填法就是按照 \(1,n^2,2,n^2-1,3,n^2-2 ……\) 的顺序,依次填进一条能够走完整个网格的路径。
光是这一点我都想了半天怎么构造,然后想出来后傻乎乎地写了个深搜,让它旋转地绕圈地走,浪费大把时间。
知道这个之后我们完全可以这么走:就行了……
- Yet Another Tournament CF1783C \(\color{red} 耻辱!\)
思考时间过长+想复杂了
曾经在这里发了电,太逆天了所以删了。
我试用了一个及其复杂的做法,就是先贪心,能杀就杀,如果还剩一发,只能再多杀一个人,我其实就知道了我一共能杀多少人。
找到那个和我杀的人数量相同的人,把他杀了就行;找不到就摆。
- Game of the Year CF1783E \(\color{red} 耻辱!\)
从12.22开始做,最开始想了个 \(O(n \sqrt {n} )\) 的整除分块
具体来说是这样的:对于每个 \(a_i\) 和 \(b_i\),
若 \(a_i \le b_i\) 则任何 \(k\) 都能选;
若 \(a_i > b_i\) 则只有满足以下条件的 \(k\) 能选:
\(( \left\lfloor\frac{b_i}{k}\right\rfloor +1) \times k \ge a_i\) ,等同于\(k \ge \frac{a_i}{\left\lfloor\frac{b_i}{k}\right\rfloor +1}\)。
然后分母可以整除分块,每一块内的分母都相等,直接算就行了,但常数巨大且卡不掉,暴死。
然后就各种想,各种不会,一直想来想去想不出来咋做,极为焦虑地过完了这一周。
最接近答案的成果是推出了一个东西:
对于 \(a_i\) 和 \(b_i\) 来说,\(b_i \le k < a_i\) ;\(\frac{b_i}{2} \le k < \frac{a_i}{2}\) ; \(\frac{b_i}{3} \le k < \frac{a_i}{3}\) ……这些 \(k\) 都不能选
去一下分母,就成了 \(b_i \le k < a_i\) ;\(b_i \le 2k < a_i\) ; \(b_i\le 3k < a_i\) ……
然后就可以 \(O(n \log n)\) 做了,枚举每一个 \(k\) ,然后枚举 \(k\) 在 \(n\) 以内的倍数,如果所有的倍数都不处于任何一对 \(a_i\) 和 \(b_i\) 之间,那么这个 \(k\) 就是可以选的;但凡有一个出现了,那就不能选。
第十七场-CF1882
最好是填一个 \(1,2,……n\) 的序列,由于要求字典序最小,所以如果当前填不了就加一,然后填下去就行了。
- Sets and Union CF1882B \(\color{red} 耻辱!\)
这破题当成图论做也真的是逆天。
删掉每个数会使哪些数连带着被删,用这个关系建有向图,从每个点开始 dfs,就行了。
感觉不如枚举,但不会枚举。
如果第一张是正数的话,可以先放着不管,总有一种取法,使这张牌之后的所有正数牌都可以取到。
否则,第三张牌及以后的正数牌总能取到,第一张和第二张要么都要,要么都不要,看那种价值更大就行。
小换根 dp。
通过手玩样例,发现一个贪心策略:对于一个节点 \(x\),记 \(x\) 共有 \(tot_x\) 个儿子,记它的儿子分别为 \(son_{x,1},son_{x,2}……son_{x,tot_x}\),记它的父亲为 \(fa_x\)。
则可以先把 每个 \(son_i\) 的子树统一为 \(w_{son_i}\),然后在 \(son_i\) 处选取 \(c=w_x \oplus w_{son_i}\),进行一次操作,把 \(son_i\) 的子树的所有节点权值都变成 \(w_x\)。
然后先从 \(1\) 开始跑一遍 dp,记 \(dp[x]\) 为把 \(x\) 的子树中所有节点的权值都变成 \(w_x\) 的代价。
转移式:\(dp[x]=\sum\limits_{i=1}^{tot_x} \bigg(dp[son_{x,i}]+sze_{son_{x,i}}\times (w_{son_{x,i}} \oplus w_x)\bigg)\)。
开始换根!记 \(dp2[i]\) 为以 \(i\) 为根时,只把 \(fa_i\) 所在子树统一成 \(w_i\) 的代价。
转移式:\(\begin{aligned}dp2[i]=dp2[fa_i] + (w_i\oplus w_{fa_i}) \times (sze_1-sze_i) \\+ dp[fa_i] - (dp[i] + sze_i \times (w_i \oplus w_{fa_i}) )\end{aligned}\)
具体的含义为:第一行:把 \(fa_{fa_i}\) 转化为 \(fa_i\) 的代价为 \(dp2[fa_i]\),再把这部分权值为 \(w_{fa_i}\) 转化为 \(w_i\) 的代价。
第二行:把 \(fa_i\) 除了 \(i\) 的儿子,全变成 \(w_{fa_i}\),再变成 \(w_i\) 的代价(其实就是 \(dp[fa_i]\),再减去原先 \(dp[i]\) 向 \(dp[fa_i]\) 转移的代价)。
第三遍:记 \(ans[i]\) 为以 \(i\) 为根时的代价。
计算式:\(\begin{aligned}ans[i] = dp2[fa_i] + dp[i] + (w_i\oplus w_{fa_i}) \times (sze_1-sze_i)\\ +dp[fa_i] - (dp[i] + sze_i \times (w_i \oplus w_{fa_i}) ) \end{aligned}\)
深搜搜一遍就行了。
第十八场-CF1739
枚举并 check 一下,没啥好说的。
模拟一遍 \(a\) 的构造,假设此时 \(a_1 \sim a_{i-1}\) 已经构造出来且唯一存在。
如果 \(d_i>0\),且 \(a_{i-1} -d_i\ge 0\),则 \(a_i\) 可以选择填 \(a_i+d_i\) 或 \(a_i-d_i\) 皆可,\(a\) 就不唯一确定了。
枚举一遍后如果没有出现任何这样的问题,就唯一确定了。
假设 \(ans_n\) 为 Alice 赢的方案数,那么存在一个递推式:
\(ans_i=C(i-1,i/2-1) + C(i-4,i/2-3) + ans_{i-4}\)。
这个的正确性可以尝试手玩玩出来,写这篇博客时已经距离我玩出来的时候太远了,所以我也没办法解释这玩意的正确性了……
任何时候平局只有一种可能,所以 Bob 赢的方案数 就是 \(C(n,n/2)-ans_n-1\) 。
第十九场-CF1721
手玩几组,输出规律即可。
先写了广搜,但由于没有保证 \(\sum m,\sum n \le 1000\),就 T 飞了。
所以其实只需要看一看激光会不会挡住路,挡住了就是 \(-1\),否则就是 \(n+m-2\)。
我们维护一个 \(R\),最初 \(R=n\)。倒序枚举 \(i\)。
对于每个 \(a_i\),找到最小的 \(b_j\ge a_i\),则 \(dmin_i=b_j-a_i\),$ dmax_i=b_R-a_i$。
如果此时 \(j=i\),就令 \(R=i-1\),意味着 \(a_{i\sim n}\) 要和 \(b_{i\sim n}\) 匹配,后续的 \(a_i\) 只能选取 \(i-1\) 之前的 \(b\) 了。
考虑从高位到低位枚举,最开始序列被分成 \(1\) 段。假设当前枚举到第 \(k\) 位,一共分成了 \(cnt\) 段。
对于每一段,找到 \(a\) 中这一段里第 \(k\) 位为 \(0\) 的出现次数,和\(b\) 中这一段里第 \(k\) 位为 \(1\) 的出现次数。
如果两者相等,就把这一位是 \(0\) 的 \(a\),和这一位是 \(1\) 的 \(b\) 放在这一段的最前头,然后把这一段分成两段。
如果所有的段的这一位都满足如上条件,那么 \(f(a,b)\) 的这一位就可以为 \(1\),累加进答案。
不停地分就行了。
- Prefix Function Queries CF1721E \(\color{red} 耻辱!\)
非常好题目,算是看了半个题解。意思是说kmp忘了咋写了,于是翻了翻蓝书。
先把 \(s\) 的 \(nxt\) 数组求出来,然后考虑把一部分 拥有相同前缀的 \(t\) 放在一起,同时计算 \(nxt\)。
然后就是把询问排序后不停地分治,可以省略很多次重复计算 \(nxt\)。
这样就可以高效地处理询问了!这个做法和曾经的 Fixed Prefix Permutations CF1792D 这道题非常像,用的是相同的思想!
第二十场-CF1661
每一对数都尝试交换,看换和不换那个更小。
因为 \(32768=2^15\),所以一个数最多 \(15\) 次操作就能变成 \(0\)。预处理一个 \(GO_x\),表示 \(x\) 最多乘几个 \(2\) 就是 \(32768\) 的倍数。
然后预处理一下 \(GO\) 和 \(ans\),就行了。
先寻找一个最终所有树相等的一个高度,记为 \(fin\)。
记录 \(p_i=fin-h_i\),\(tot=\sum\limits_{i-1}^{n}(p_i\bmod 2=1)\),\(sum=\sum\limits_{i-1}^{n}p_i -tot\)。
对于每一个 \(p_i \bmod 2=1\),至少需要用一次 \(1\) 使其变偶。
-
如果 \(tot=\frac{sum}{2}\),意味着刚好可以一次 \(1\),一次 \(2\) 交替使用,答案为 \(sum\)。
-
如果 \(tot>\frac{sum}{2}\),意味着用了几次 \(1\) 之后,没有 \(2\) 可以供剩下的 \(1\) 用了,此时答案为 \(sum\);
为了用完剩余的 \(1\),每一个 \(1\) 都需要用一次,等一天(当然最后一个 \(1\) 不用等)。所以此时答案又加上 \(2\cdot tot-1\),总共就是 \(sum+2\cdot tot-1\)。
- 如果 \(tot<\frac{sum}{2}\),意味着把 \(1\) 用完后,还有好多 \(2\) 没有用。记此时有 \(cnt=\frac{sum}{2}-tot\) 个 \(2\)。
我们可以每操作四次,\(-1-2-1-2\) 共减掉 \(3\) 个 \(2\)。
如果 \(cnt \bmod 3=0\),则刚好可以通过 \(\frac{cnt}{3}\times 4\) 次操作,减掉所有的 \(2\)。
如果 \(cnt \bmod 3=1\),则通过 \(\left\lfloor\dfrac{cnt}{3}\right\rfloor \times 4\) 次操作,把 \(2\) 减得只剩下一个。
这剩下的一个 \(2\) 可以先等一天再减一下,此时又新加上 \(2\) 次操作。
如果如果 \(cnt \bmod 3=2\),则通过 \(\left\lfloor\dfrac{cnt}{3}\right\rfloor \times 4\) 次操作,把 \(2\) 减得只剩下两个。
剩下的 \(4\) 可以通过 \(3\) 次操作:\(-1-2-1\) 完成。此时又新加上 \(3\) 次操作。
这种大情况下,总操作次数就是:
而关于 \(fin\) 的选取,选一下 \(maxn=\max\limits_{i=1}^na_i\),再选一下 \(maxn+1\),再选一下 \(maxn+2\),多试几下就行了。
区间减等差数列,要求操作次数最小。
倒着考虑,维护一个 \(now\) 来累计之前减的等差数列对 \(a_i\) 的影响。可以用一个后缀和,来维护 \(now\)。
此时 \(a_i\) 的真实值是 \(a_i-now\),然后考虑以 \(a_i\) 为末尾使用 \(\left\lceil \dfrac{a_i-now}{k}\right\rceil\) 次操作,然后算算对前面的影响。
这样枚举几遍就行了。
Part 3.第二十一场~第三十二场
第二十一场-CF1814
分类讨论,若 \(n\) 是偶数,直接输出 YES。
若 \(n\) 是奇数,\(k\) 是偶数,直接输出 NO。
其他情况就是 YES 了。
最开始尝试把 \(a\),\(b\) 的因数(\(1e9\) 的因数个数是 \(1000\) 级别)找到,然后分别枚举,计算。
然后马上就找到了hack:a=1,b=11。
然后尝试枚举 \(\sqrt{a}\) 和 \(\sqrt{b}\),马上就发现超时了,紧接着就去做C题了。
做完后拐回来一看,发现题目本质就是让你找一个 \(mend\)(这个词的组成是 \(m+end\)),使分别只用 \(mend\) 内的数拼成 \(a\) 和 \(b\) 的次数,加上 \(mend-1\) 最小。
其实等同于求这个的最小值:
\(\left\lceil\dfrac{a}{mend}\right\rceil + \left\lceil\dfrac{b}{mend}\right\rceil + mend - 1\)
扔进 desmos 一看,我趣!对勾函数!
事实上,把上取整去掉,这就是个对勾函数,当 \(mend=\sqrt{a+b}\) 时取最小值。
戴上了上取整咋办捏?充分发扬人类智慧可知正确决策距离 \(\sqrt{a+b}\) 不远,于是枚举 \(-100\le del \le 100\),分别令 \(mend=\sqrt{a+b} + del\)统计答案,就解决了此题!
大水题,序列倒序排序一下,当前数让当前完成时间较少的那个机器完成,分类一下输出就行了。
为什么不和B题对调一下?
好题,写成题解了:CF1814E Chain Chips 题解。
第二十二场-CF1809
全相同为 \(-1\)、有四种不同颜色、三种不同颜色、两种颜色一种一个另一种两个,都为 \(4\)、有两种颜色各两个为 \(6\),直接输出答案即可。
- Points on Plane CF1809B \(\color{red} 耻辱!\)
曾经我在这里大骂一通这个题,后来发现没什么实质性作用,就删了。
明确一下,这题一共有两种填法:
第一种:
前 \(n\) 层地个数分别为 \(1,9,25……\)代价分别为 \(0,2,4……\)。可以用二分查找 \(n\) 个点所在层数即可。
第二种:
前 \(n\) 层地个数分别为 \(4,16,36……\)代价分别为 \(1,3,5……\)。可以用二分查找 \(n\) 个点所在层数即可。
两种染法取 \(\min\),输出即可。
非常好构造题,先二分找到一个最大的 \(m\),使得 \(\sum\limits_{i=1}^{m} i \le k\),然后令 \(a_1 \sim a_m\) 都为 \(2\)。
此时 \(0 \le k-m \le m\),我们需要在第 \(m+1\) 个位置填上一个合适的负数,使得刚好以 \(a_1 \sim a_{k-m}\) 为左端点, 以 \(a_{m+1}\) 为右端点的 \(k-m\) 个区间的和为正数,显然可以填 \(-((2m-k) \times 2 +1)\) ,如果还剩下一些位置,就填上 \(-1000\)。
先想一个弱化版问题:如果只有删数运算,怎么删花费最小。
枚举一个 \(1\le i \le n+1\),将 \(a_i \sim a_n\) 中的 \(0\) 删去,将\(a_1 \sim a_{i-1}\) 中的 \(1\) 删去,就是本次操作的答案;将所有答案取 \(\min\) 即可。
段内的 \(0\) 和 \(1\) 的个数可以前缀和统计。
而带上了交换操作后,仍然这样枚举,当枚举到 \(i\) 时:
若 \(a_i\) 为 \(1\),且 \(a_{i+1} \sim a_{i+t}\) 都是 \(0\),则原本的 \(t\) 次删除操作就可以换成 \(t\) 次交换操作,以减少答案。
同理,此时若 \(a_{i-1}\) 为 \(0\),且 \(a_{i-t-1} \sim a_{i-2}\) 都是 \(0\),则原本的 \(t\) 次删除操作就可以换成 \(t\) 次交换操作,以减少答案。
统计一下每个 \(1\) 后面有多少 \(0\),和每个 \(0\) 前面有多少 \(1\)。
在每个 \(i\) 时分别只取用上述的一种更改(不能同时取用,不然中间就会有一对 \(10\)),更新答案即可。
第二十三场-CF1796
把这个FB的字符串的前 \(100\) 位枚举出来,枚举一定数量个起点,匹配一下试一试就行了……
第一次做这个题的时候我甚至还在枚举起点时 \(3,6,9……\) 然后把串构造出来,再看相不相等,现在想想太离谱了,如果没这么做的话D题应该就能场切了……
如果两个串有相同的长度为2的子段(记为 \(S\)),就输出 *S*
。
否则如果两个串第一位相同(记为 \(s1\)),就输出 s1*
。
否则如果两个串最末位相同(记为 \(s2\)),就输出 *s2
。
否则无解。
从最开始的 \(O(n \log n)\),到后来的 \(O(n)\),再到最后的 \(O(1)\),非常爽!
当这个集合的最小元素选 \(l\),每一次加入新的元素都是上一次元素的二倍时,得到的元素个数就是第一问的答案,为 \(\log_2(r-l+1)+1\),记 \(\log_2{r-l+1}\) 为 \(ans1\)。
此时,我们考虑左端点最大为多少时,乘以 \(2^{ans1}\) 不会超过 \(r\),很显然是 \(\frac{r}{2^{ans1}}\)。
每一个这样的的区间都可以为 \(ans2\) 提供大小为 \(1\) 的贡献。
根据 \(ans1\) 的最大性,我们最多可以将一个 \(\times2\) 换成 \(\times 3\)。
考虑换完之后左端点最大为多少,显然是 \(\frac{r}{2^{ans1 -1}\times 3}\)。
每一个换成 \(\times 3\) 的区间都可以为 \(ans2\) 提供大小为 \(ans1\) 的贡献。
最后输出答案为 \(ans1+1\),\(ans2\)。
差点就场切了,非常可惜。
\(dp[i][j]\) 表示前 \(i\) 个数,操作 \(j\) 次,以 \(i\) 为结尾的最大子段和。
for(int i=1;i<=n;i++){
for(int j=0;j<=min(k,(ll)i);j++){
ll tmp1=0,tmp2=0;
if(i>j) tmp1=a[i]-x + max(dp[i-1][j],0ll);
if(j>0) tmp2=a[i]+x + max(dp[i-1][j-1],0ll);
dp[i][j]=max(max(tmp1,tmp2),0ll);
if(n-i>=k-j)ans=max(ans,dp[i][j]);
}
}printf("%lld\n",ans);
\(tmp1\) 为第 \(i\) 个位置不操作时的最大子段和,\(tmp2\) 为第 \(i\) 个位置操作时的最大子段和。
有很多细节,因此没有场切
1.只有当 \(i>j\) 时才能统计 \(tmp1\),否则第 \(i\) 为必须得选。
2.只有当 \(j>0\) 时才能统计 \(tmp2\),否则 \(j\) 为 \(0\),选不了,没有意义。
3.统计答案的时机很怪,当 \(i+1 \sim n\) 这些数的数量要大于等于没用完的操作数(即 \(k-j\))时,就可以统计答案。
\(\color{gold}第二十四场-CF1795\)
放在最前头:金色传说!!!场内切了五个!!!
把 \(b\) 串翻转一下,拼在 \(a\) 串后面,记 \(tot\) 为此时这个串中长度为二且这两位相同的子串个数。
若 \(tot \le 1\) 则输出 YES;否则输出 NO。
先把所有不覆盖 \(k\) 的线段删去,显然优。
然后算出每个点被覆盖的次数,可以差分也可以直接遍历(毕竟 \(n\le50\))。
枚举除了 \(k\) 以外的每个点,若该点覆盖次数等于 \(k\) 的覆盖次数,则无解。若不存在这样的点,则有解。
对于每一杯茶,二分查找出它被喝完的时那个人。
具体来说,对于第 \(i\) 杯茶,二分查找出一个位置 \(k\),使得 \(\sum\limits_{j=i}^{k}b_j \le a_i < \sum\limits_{j=i}^{k+1}b_j\)。
然后使用一个 double 类型的差分数组,在 \(cha_i\) 上加 \(1.0\) ,在 \(cha_{k+1}\) 上减 \(1.0\)。对于第 \(k+1\) 个人喝完了这杯茶的最后一部分。
记 \(tmp= a_i-\sum\limits_{j=i}^{k}b_j\),则在 \(cha_{k+1}\) 上加 \(\frac{tmp}{a_{k+1}}\) ,在 \(cha_{k+2}\) 上减 \(\frac{tmp}{a_{k+1}}\)。
最后把差分数组求前缀和,第 \(i\) 个人喝的茶的数量就是 \(cha_i \times b_i\)。
看着吓唬人,实则纯纯的水题。
一共有 \(\frac{n}{3}\) 个三角形,显然每个三角形最多只有两条边被染色。
而因为保证了染蓝色和染红色的数量相同,所以可以给某 \(\frac{n}{6}\) 个三角形染成两红一篮,给剩余的 \(\frac{n}{6}\) 个三角形染成两蓝一红。
此时染色给答案的贡献为 \(C_n^{\frac{n}{2}}\)。
此时问题就转化成了每个三角形选出一条边,使得选出的边之和最小。显然,选法就是每个三角形选出其中三条边的最小值。
而对于某个三角形,如果有多条最小值边,则可以选择任意一条,所以此时对答案的贡献为 \(\prod\limits_{i-1}^{\frac{n}{3}} tot_i\)(\(tot_i\) 是指第 \(i\) 个三角形的最小边的数量)。
总答案就是 \(C_n^{\frac{n}{2}} \times \prod\limits_{i-1}^{\frac{n}{3}} tot_i\)。
这是我在这么多场比赛第一次把一个 dp 分成左贡献和右贡献。
记 \(dp[i][op]\) 为在第 \(i\) 个位置使用爆炸,其前面的怪物的普攻最小值。(\(op=0\) 时为原序列,\(op=1\) 时为翻转后的原序列(因为左贡献和右贡献算法相同,反转序列就够了))
记 \(t_i=h_i-i\),\(s_i=\sum\limits_{j=1}^{i} h_i\)。
外层循环枚举 \(1 \le i \le n\)。当枚举到 \(i\) 时,先找到最大的一个 \(j\) 满足 \(t_j<t_i\)(不存在的话 \(j=0\)),含义是 在 \(j+1 \sim i\) 这些怪物中,\(i\) 处使用一个爆炸后,爆炸的威力只会每次衰减 \(1\)。
\(j+1 \sim i\) 这一段的贡献就是 \(res1=s_i - s_j - \sum\limits_{k=0}^{\max(0,h[i]-(i-j-1))}(h_i-k)\)。
碰到第 \(j\) 个怪物之后,爆炸威力就衰减到了 \(h_j -1\),此时 \(1 \sim j\) 这一段的贡献就是 \(res2=dp[j][op]\)。
所以总转移式就是:\(dp[i][op]=res1+res2=s_i - s_j - \sum\limits_{k=0}^{\max(0,h[i]-(i-j-1))}(h_i-k)+dp[j][op]\)。
统计答案:\(ans=\min\limits_{i=1}^{n}(h_i + dp[n-i+1][0] + dp[i][1])\)(主要是因为此时 \(h\) 已经翻转过了,所以是 \(op=0\) 那一部分为 \(n-i+1\))。
好!!!!!!!!
第二十五场-CF1767
当这个三角形是直角三角形,且直角是横平竖直时,输出NO。
那就枚举某一个顶点是直角顶点,根据坐标判断一下就行了。
把 \(a_2 \sim a_n\) 排个序,枚举 \(2 \le i \le n\),如果 \(a_i \ge a_1\),就把 \(a_i\) 不停地给 \(a_1\),直到给不动为止。
这样遍历一遍之后的 \(a_1\) 就是答案。
这题没补,先写一下现有的思路,方便以后再补。
首先把所有 \(a=1\) 的线段放在一起排个序,枚举一下就可以把原序列划分为 \(tp\) 个连续的段,每个段内的染色必须相同。
这些段从 \(1\) 开始编个号,记为 \(1 \sim tp\)。
每一个 \(a=2\) 都可以视作这样一个条件:编号从 \(l_i \sim r_i\) 的段中,至少有两个段颜色不同。
此时若 \(l_i = r_i\) 则无解。
然后不会了!!!
记 \(wins[j][i]\) 表示第 \(j\) 个人能否作为前 \(i\) 轮的赢家。
讨论 \(s_i=0\)。
当且仅当存在一个 \(k>j\),且 \(k\) 和 \(j\) 都能在前 \(i-1\) 轮胜出,并且两者的获胜方案不相交时,\(wins[j][i]=1\)。
如何判断相交不相交?\(s_i=0\) 意味着 \(j\) 和 \(k\) 需要足够数量的,比分别他们两个大的人,以供他们战胜。
他们需要多少个人呢?假如前 \(i\) 场有 \(t\) 个 \(0\),则算上 \(j\) 和 \(k\),一共需要让 \(2^n-j+1\) 中存在 \(2^t\) 个数,也就是\(2^n-j+1 \ge 2^t\),就可以满足不相交的条件。
然后 dp 地统计答案就好了。
第二十六场-CF1766
用前缀和预处理一下 \(10^6\) 以内的 \(n\) 的答案,直接输出即可。
枚举,把当前出现过的长度为二的子串扔进一个 map 里。然后查找当前 \(i-1\) 和 \(i\) 构成的子串出现过没有即可。如果从来都没出现过,就输出 NO。否则YES。
枚举 \(1\le i \le n\)。记录一个 \(now\) 代表当前走到了那一行。如果走不动了就寄掉了,否则就往右走一步,然后看看自己上面或者下面要不要走,要走的话就必须走,就走一下,更新一下 \(now\)。
乱搞一下就行了。
- Lucky Chains CF1766D \(\color{red} 耻辱!\)
显然,如果当前 \(gcd >1\),直接输出 \(0\)。
如果 \(|x-y|=1\),就输出 \(-1\)。
对于剩余的情况,令 \(x>y\),记 \(x+k\) 和 \(y+k\) 的 \(gcd\) 为 \(d\) ,则 \(d | (x+k)-(y+k)=(x-y)\)。
这意味着我们要找到 \(x-y\) 的一个因数 \(d\),满足 \(d- (x\bmod d)\) 最小。
A后二编:事实上,我们只需要枚举 \(x-y\) 的所有质因数,就可以了(因为在达到一个合数的倍数前,一定会先达到这个合数的某个质因子)。
如何快速找到 \(x-y\) 的所有质因数呢?我们在线性筛的同时就求出了每个数的最小质因子,记 \(tmp=x-y\),我们只需要不停地先尝试 \(tmp\) 的最小质因子,然后把 \(tmp\) 的所有质因子除掉,while 一下就行了。
第二十七场-CF1749
知道 \(n\) 和 \(m\) 就够了。如果 \(n=m\),输出 NO;否则输出 YES。
- Death's Blessing CF1749B \(\color{red}耻辱!\)
我最开始甚至在链表模拟……
\(ans=\sum a +\sum b -\max b\)。
原理就是所有的 \(a\) 的时间都要花费;而每次只删最左边或最右边的话,来自 \(b\) 的贡献就是 \(\sum b- b_{x}\),其中 \(x\) 可以取任意值。
为了让 \(ans\) 最小,就让 \(b_x\) 取成 \(b_{max}\) 就行了。
二分答案,假设当前答案为 \(mid\)。
因为 \(n\le 100\),所以可以直接模拟这 \(mid\) 轮二人的操作。
假设当前是第 \(i\) 轮。
第一个人从当前没有被删除的数中,找到最大的 \(x\) 保证 \(x\le mid-i+1\)
第二个人给当前没有被删除的数中,最小的数加上 \(mid-i+1\)。
模拟一遍,看第一个人能否删完 \(mid\) 个数。
如果考虑孬序列的个数不好考虑的话,正难则反,考虑不孬的序列个数,记为 \(res\),答案就是 \(\sum\limits_{i=1}^{n}m^i - res\)。
考虑一下不孬的序列实质是什么,显然就是满足这样的序列:对于每个 \(2\le i \le n\),满足对于 \(2\le j \le i\),\(gcd(a_i,j)\not=1\)。
将 \(i!\) 分解质因数,记 \(i! = \prod\limits_{j=1}^{tot}p_j^{c_j}\),则记 \(t=\prod\limits_{j=1}^{tot}p_j\),则对于 \(a_i\) 来说,任何 \(k \times t \Big(1\le k \le \left\lfloor\dfrac{m}{t}\right\rfloor\Big)\) 都可以选。
所以当序列长度为 \(i\) 时,不孬的序列个数为 每个位置可以选的数的个数 的乘积,即为\(\prod\limits_{j=1}^{i}\left\lfloor\dfrac{m}{t_j}\right\rfloor\)。
此时我们就可以表示答案了:\(ans= \sum\limits_{i=1}^{n}m^i - \sum\limits_{i=2}^{n} \prod\limits_{j=1}^{i}\left\lfloor\dfrac{m}{\prod\limits_{k=1}^{tot_j}p_{j,k}}\right\rfloor\)
第二十八场-CF1743
\(ans=6 \times C_{10-n}^{2}\)。
第一位放 \(1\),剩下的位置放 \(n \sim 2\)。
- Save the Magazines CF1743C \(\color{red}耻辱!\)
不读题导致的,以为每个板子都可以往左或往右,浪费大把时间。
把原序列划分为多个连续的 \(1\) 段,同时统计每个段的最小值 \(minn_i\)。
对于第 \(i\) 段,若 \(l_i \not= 1\) 且 \(minn_i\le a_{l_i}\),就把从 \(l_i\) 到 \(pos_i\)(\(minn_i\) 的位置) 这些板子同时往右移一位,这样可以使答案变大 \(a_{l_i}-minn_i\)。扫完后输出答案即可。
数据随机,所以乱搞就行。
找到最左边第一个 \(1\),位置记为 \(pos1\);找到 \(pos1\) 之后第一个 \(0\),位置记为 \(pos2\)。
分别把 \(s\) 右移 \(1 \sim pos1-pos2\)位,与原串或一下,统计最大值即可(由于数据随机,所以实际上 \(pos1-pos2\) 很小)。
第二十九场-CF1728
输出最大值所在位置。
显然答案最大就是 \(2\times n-1\)。所以在第 \(n\) 个位置放 \(n\),在第 \(n-1\) 个位置放 \(n-1\)。
如果 \(n\bmod 2=0\),就依次把 \(n-2 \sim 1\) 放进 \(p_1 \sim p_{n-2}\)。这样可以两两抵消,在第 \(n-2\) 个位置结束后 \(X=0\)。
如果 \(n\bmod 2=1\),就先把 \(1 \sim 3\) 放进 \(p_1 \sim p_3\),然后依次把 \(n-2 \sim 4\) 放进 \(p_4 \sim p_{n-2}\)。这样 \(1 \sim 3\) 互相抵消,剩余的两两抵消,在第 \(n-2\) 个位置结束后 \(X=0\)。
转化题意:给定两个可重集合,是用最少的操作次数,使得两个集合相等。
先把 \(a\) 存进 map,把 \(b\) 里面与其相等的直接匹配。
对于不匹配的,用操作把 \(a\) 和 \(b\) 中 \(x>9\) 的数转化成 \(0\le f(x)\le9\)。再进行一次匹配,相同的直接匹配。
对于剩下的,不为 \(1\) 的数,用操作将其转化成 \(1\),就结束了。
赛后五秒钟切出来。如何评价?
首先可以明确一点,手玩几组发现Bob 无论如何也赢不了(至于为啥我也不知道)。所以 Bob 所能做的就是尽可能平局。
设 \(dp[i][j]\) 为对于 \(i \sim j\)这一段区间 (记 \(len=j-i+1\))。
若 \(len \bmod 2=0\),则 Alice 面对 \(s_{i\sim j}\) 这一段字符,能否取胜(能则 \(dp[i][j]=1\),否则 \(dp[i][j]=0\))。
若 \(len \bmod 2=0\),则 Bob 面对 \(s_{i\sim j}\) 这一段字符,能否取一步后让剩下的局面两人平局(能则 \(dp[i][j]=1\),否则 \(dp[i][j]=0\))。
设 \(wh[i][j]\) 为 \(dp[i][j]=1\) 时这个人要取走哪个字符。
转移方程:
当 \(len \bmod 2 =1\):
\(dp[i][j]=\begin{cases}1 &{dp[i+1][j]=0 \text{ or }dp[i][j-1]=0}\\0&{\text{other cases}}\end{cases}\),\(wh[i][j]=\begin{cases}s[i] &{dp[i+1][j]=0}\\s[j] &{dp[i][j-1]=0}\\z+1&{\text{other cases}}\end{cases}\)
当 \(len \bmod 2 =0\):
\(dp[i][j]=\begin{cases}1 &{\begin{cases}dp[i+1][j]=0 \text{ or }dp[i][j-1]=0\\s[i]<wh[i+1][j]\\s[j]<wh[i][j-1]\end{cases}}\\0&{\text{other cases}}\end{cases}\)
\(wh[i][j]=\begin{cases}s[i] &{dp[i+1][j]=0 \text{ or } s[i]<wh[i+1][j]}\\s[j] &{dp[i][j-1]=0 \text{ or } s[j]<wh[i][j-1]}\\z+1&{\text{other cases}}\end{cases}\)
最后如果 \(dp[1][n]=1\),则 Alice 获胜;否则平局。
第三十场-CF1671
把 \(s\) 划分为几个连续的\(a\) 段和 \(b\) 段,不存在长度为一的段就输出 YES。
- Consecutive Points Segment CF1671B \(\color{red}耻辱!\)
把原序列划分为几个连续的斜率为一的段,对端的个数进行讨论。
只有一段显然可以;只有两段的话交点处的差 \(\le3\) 就行;只有三段的话两处交点的差必须都为 \(2\) 才行;段数 \(\ge 4\) 的都不行。
对于某个时刻来说,想要买更多的糖,肯定是挑价格最便宜的几包来买,所以随着日子的增多,购买方案只会不停地减少其中的最大值者。
所以可以先排个序,求个前缀和,对于每个前缀和计算 \(tmp_i=\frac{x-sum_i}{i} +1\) 为只买前 \(i\) 包糖能买几天。
记最大的 \(i\) 满足 \(tmp_i>0\) 为 \(tot\),则肯定是在第 \(1 \sim tmp_{tot}\) 天里,每天买 \(tot\) 包糖,\(tmp_{tot}+1 \sim tmp_{tot-1}\) 天里每天买 \(tot-1\) 包糖……
这个东西枚举一遍就算出来了,这题就做完了。
记 \(maxn=\max\limits_{i=1}^{n}a_i\),\(minn=\min\limits_{i=1}^{n}a_i\)。则 \(1\sim k\) 与 \(minn \sim maxn\) 的并集部分可以直接塞进 \(a\) 序列中 \(minn\) 和 \(maxn\) 所在位置之间,这些数不会对原序列的分数产生任何影响。
然后考虑 \(\le minn\) 和 \(\ge maxn\) 段的位置安排了。对于 \(1 \sim minn\) 段,有三个位置可以放:\(a_1\) 前、与 \(minn\) 相邻、\(a_n\) 后。
三种方法对分数的影响分别是加上:\(a_1-1\)、\(2 \times (minn-1)\)、\(a_n-1\)。 \(maxn \sim k\) 段同理。
毕竟这两段不能同时占用 序列最前头或序列最后头,所以分类讨论一下就行了。
放在最前头:div.2 的比赛,A \(\sim\) E 出个红橙黄黄绿也真是离谱!E 题甚至是道 2100 分的题!太抽象了!
非常简单 dp,记 \(dp[i]\) 为 \(i\) 这个节点和它的子树的变化方案。
如果以 \(i\times 2\) 和 \(i \times 2+1\) 为根的两颗子树能够通过在各自内部通过交换儿子实现两者相同,则 \(dp[i]=dp[i\times 2] \times dp[i\times 2+1]\);否则 \(dp[i]=2\times dp[i\times 2] \times dp[i\times 2+1]\)。
每个节点的子树能否本质上相同,可以预处理:把每个节点的左右儿子交换成 左小右大,就可以直接通过两颗子树的前序遍历是否相等来判断是否本质相同了。