这里是最后两个月的比赛总结,从吾心,尽吾力,可以无悔矣。
UPDATE:2021 5.23 在打多次模拟赛之后 我终于发现了自己的问题。一直困扰着我的问题。
实力的进步达到了瓶颈期 我一直在思考是为什么 可能就是自己的多角度思考问题 乱搞能力 过差 很多题目都只差临门一脚 却踢不出来 性质一直把握不好 也不知道如何使用是我最大的弊病。
我在思考如何解决 如何渡过 如果在接下来的十几日没有取得突破 我恐怕 会抱憾终生吧.
谨以此 敲响我心中的 死钟.
发现的几个小trick:
vector里lower_bound 如果没有的话应该会范围end这个迭代器 如果存在的话-begin迭代器之后返回的就是在vector中的位置了.
lower_bound+set 复杂度即可 而使用set中的lower_bound复杂度则为nlogn.
2020 1 10 牛客练习赛57
犯了几个sb错误 如 代码写的有误 字符打错等,没有好好对待比赛题目,过于紧张了。
经典NPC问题:[装货物](https://ac.nowcoder.com/acm/contest/3781/C)
怎么做?显然搜索不行 状压 $f[i]$表示...然后预处理一发,状态转移发现需要枚举子集 复杂度$3^n$ 会T。
到这里我们已经被惯性思维给控制住了 状态并非只需要枚举子集我们完全可以枚举下一个拿哪一个箱子,显然这需要另一个状态来加持即g[i]表示形成这个状态最后一个箱子剩余的最大容量这样可以保证使答案不会变的更差。
复杂度$2^n\cdot n$ 可以通过。
[E题划分树](https://ac.nowcoder.com/acm/contest/3781/E)
这道题是比较特殊的树形dp 我没有见过的树形的模型觉得很不可做 其实真正的做法是这样的。
对于把树划分成若干个联通块 每个连通块的异或和都是M 以前是小于等于M 然后设状态疯狂转移 最后复杂度好像是$nm^2$的。
这个题M很大无法设计状态 f[i][j]表示i字数内删掉若干条边异或和为j的方案数进行转移况且这个状态也很难转移。
考虑问题的特异性,特异性1 对于树上的某个节点来说子树异或和不为M或0的话那么意味着不管怎么划分都无法把所有子树都划分为M. 显然。
那么显然对于一个点来说我们考察其子树内的点权异或和是否为M或0 咕了。[代码](https://paste.ubuntu.com/p/3dgTNDh7Bb/)
2020 1 15 EC codeforeces R 80 div2
先说犯的错误吧做题时不冷静盲目交题 不仔细推理而是盲目的写 没有仔细观察性质 可能就差一点 就知道了呢?
[A题](https://codeforces.com/contest/1288/problem/A)
这道题很气做了好久一直挂不知道为什么 结论错了 猜了好几个结论 最后x是取 $\sqrt{d}$和$\sqrt{d}-1$有点不敏感了 均值不等式我一直在看右边 既然wa了就不要重复提交要清醒 清醒别浪费过多的时间。
一个角度wa了要快速去思考另一个角度 不要在一个地方一直想 要不断换方法如上面均值不等式右边挂了就要看左边,显然由左边是可以推出答案的。
这里也有一个暴力的思路T只有50而d有1e9显然可以估一个答案的上界然后不断向下扫即可如 我们知道x取根号d的时候答案最大也就是$2*\sqrt{d}$也就是说我们从1到$2*\sqrt{d}$这个范围暴力枚举即可也是可以过的,要注意观察别犯傻。
[C题](https://codeforces.com/contest/1288/problem/C)没什么好说的常规优化dp但是我却写了很长时间 这点很不应该 要清醒的推方程。
ATC Keyence Programming Contest 2020 [E题](https://atcoder.jp/contests/keyence2020/tasks/keyence2020_e)
给了一张无向图 和一堆点权 约束条件 给每个点分黑白点 然后每个点到距其最近的相反颜色的点的路径长度等于其点权 构造出整张图的边权...
有一些小性质,考虑一下所有点中权值最小的点 和它颜色相反的点 一定和它相邻 必然且还存在一个性质 既然颜色都相反了那么对于另一个点来说 这个点的权值也应该是最小的 所以得到了一个基础的策略点权最小的点一定相邻且权值相等且颜色相反.
于是不断的考虑点权最小的点进行添加权值即可。
CF R 614 div2 掉分
原因是D题被hack了 E题没做出来 还是太菜了.
D:显然最多有60个点一个位置 我是直接寻找起点然后暴力判断往左走还是往右走的 不过起点不对 所以被hack了。
显然所有点的横纵坐标单调我们取点要么往上一直取再回来要么往下一直取再回来 可是我们发现直接往下开始取无疑是最优的 因为下面我取到最后一个点的距离和也小于我往上取一个点的距离和 所以直接暴力枚举起点 然后向下取再向上取即可。具体思考我们发现起点我们判断的话最多有两个分别从这两个点跑即可。暴力就很直接 反正只有60个点没必要优化...
E:给给出的一棵树的每一条边填上权值 形成一个0-n-1的排列 一个棵构造好的树的权值定义为所有点对之间的边的mex 求所能构造出来的树最大值权值。
看起来是构造 进一步的我们发现必须要从0到n-1一个一个填 填0发现带来的权值是这条边两遍点数之积 填1的时候带来的代价虽然两边点数之积$*2$但是刚才数填1的时候数过了所以代价还是点对数 考虑dp $f[i][j]$ 表示i点到j点的链的最大值 转移很显然,进一步的我们发现答案其实是某一个f[i][j]我们求出所有的f[i][j]取max即可。注意采用记忆化搜索。其实注意到答案其实是某一条链 我们暴力枚举每一条链计算其代价即可 记忆化只是为了不重复计算。
[CF 616 div2E 1291](https://codeforces.com/contest/1291/problem/E)
考试的时候知道是拆点但是觉得细节处理过于ex 并且思路不太清晰觉得写起来过于麻烦就崩溃了F题都没看...
思路的漏洞:纠结于一些细节:每个开关拆成两个点是显然的对于第i盏灯我一直在想如果这盏灯是亮的且能不能两个点都不选可以带来代价最小?
因为虽然开关被拆成两个点了但是其缩点的集合可能涉及到了前面点的集合也可能涉及到了后面的点的集合所以我在想有没有一种都不选的决策然后到后面迫不得已需要选择的时候再选择两个集合中权值最小的。
这个想法错的离谱,也禁锢了我的思想 拆点连边求强连通分量的时候我就觉得这题我A不了了...
不妨这样想ans表示前i-1盏灯都亮起来的答案 我们并不着急的连边当轮到i这盏灯的时候再连边保证了和后面的决策无关。
当然和前面的有关系因为前面可能和当前集合连在了一起所以进行决策时我们应该把上次的贡献减掉加入新的决策答案。
显然必须采用并查集来动态维护这种联通的关系 ,具体来讲是一个带权并查集.
值得一提的是正解和我的思路差不多(不要脸了...可以说我想出来所有细节的地方想到了这类似一个可后悔的dp。
事实证明用并查集维护这个过程绝对是再好不过了,关键是题目中给出了一定优解才能做到的下次要联系题目,不要只局限于缩点.
好题。
[ATCoder Contest 154 beginner F](https://atcoder.jp/contests/abc154/tasks/abc154_f)
一个二维平面上处在0,0点每次可以向上走一步或向下走一步,定义f(i,j)表示从(0,0)到(i,j)的方案数.
求出 r1<=x<=c1 r2<=y<=c2 f(x,y)的和 r1,r2,c1,c2<=1e6.
显然是组合数,可以$n^2$来统计答案但是会T,考虑优化 这里的一个trick是f(0,0)=1;(我没反应过来
那么我们坐标系中第一象限是一个斜着的杨辉三角。容斥一下之后我们要求整个矩形内数字的和.
还是很难求出,逐行或逐列考虑都可以考虑第i行的方案数我们把他们整体加起来刚好等于最后行末最后一个数字的上面一个数字.
逐行计算即可.(失误之处:数形结合的观念不够强,错误思路一直思考应该尝试转换角度啊啊啊。
具体解决方法:遇到自己解不出来的题目一定是性质还没有找到,很多人都过了的题一定有其解法,沉着的挖掘性质.
[XR-4 复读](https://www.luogu.com.cn/problem/P5597)
比赛的时候没想出来 看完题解之后豁然开朗,还是性质没有挖掘成功.
一颗无限向下延伸的二叉树,有一个包含根节点的联通块大小$n\leq 3000$
有三种指令L,R,U分别表示向左子走,向右子走,向父亲走 一开始机器人处在根节点 请设计一个指令,且这个指令会被多次复读,机器人会按照指令行走,求这个指令的最小长度使得机器人能把这n个关键点都至少走到一次.
很有意思的题目,我们想要求出一个最短的指令序列,显然不满足二分,因为二分之后我们还是面临着如何构造最小的指令集的问题。
题目中还有一句话是当机器人在这颗完全二叉树的根时执行U是不合法的 需要保证这种情况不出现.
性质1:假设机器人执行完了第一次指令会到达x那么接下来其再次复读之后一定只会遍历子树内的东西不可能往上走了因为如果往上的话一开始在根节点往上是不合法的。
仅有这一点性质我们发现了那么根到x这个联通块中所有点都要被遍历到 相应假设下一个点是xx 那么x到xx路径上的所有点都会被遍历到.
直到走到一个非联通块的点结束 我们把那些应该到的点拿出来发现有些相对位置是相同的所以可以合并于是合并出来的一颗树就是在指令中应该被体现的成分.
计算合并出来的树的大小即可.复杂度$n^2$.考虑一下最后的代价计算 树的大小为x 从根到当前节点的实际位移为top 注意这里树是包含最后那个节点的,
所以答案为(x-1)*2-top,除了1号节点剩下所有的节点都要进行贡献且路径上的点贡献一次.
[CF contest 1300E R618 div2 E](https://codeforces.com/contest/1300/problem/E)
这道题目的意思还是很容易理解的大体上就是你每次可以操作一个区间 让区间内的所有数字都变成他们的平均数 求若干次操作后字典序最小的序列。
贪心很容易看出来 我们尽量保证前面的尽可能的小 也就是说对于一个i来说 存在一个j 使得i~j这个区间变成平均数之后i这个位置的数字是操作其他的区间数字最小的 我们从小到大贪心即可,但这样做显然是$n^2$的 因为对于每一个i来说我们都是要再扫一遍的。所以考虑优化。
比赛的时候我很容易想到这个$n^2$的做法 于是我想到了二分这个位置 发现不具单调性 那二分 这个位置的答案 发现还需要再扫一遍才能找到位置。
我又想主席树维护...最终没有想出来 我不知道为什么我思路经常被禁锢住 每次都不往其他方向思考 毕竟当时我做到最后一道题 还有1h.
这道题的正解在我看来也是很容易思考出来的。我们发现 一个位置上的数字和另一个位置上的数字 两个数字的大小关系 如果我右边的数字比我要小 那么显然这两个数字一定是要进行合并的,我们在把刚才的做法 倒着思考 我们发现对于i找j很难找 我们对于j找i呢?我们对于当前的j来说我们不断寻找i 怎么找 也挺显然的j如果比j-1要小 那么就合并 这样不断合并到前面去我们发现对于j找i 只会合并n-1次那么这个做法就是O(n)的了。
我发现在做题的过程中有很多题目都是这个样子我们正着做非常难做 但是倒着就很容易做出来了。
这叫正难则反 非常非常非常重要的思想。
[CF1295B](https://codeforces.com/contest/1295/problem/B)
这道题在考场上出现的问题是 没有认真思考出来一个非常巧妙的方法就盲目的去写 这是很严重的错误,要把思路化简了再写 不然既费时又费力 而且最后可能还得不到一个好的结果!!!
这道题是给定一个01串且是无限循环的定义了一个前缀的权值为0的数量-1的数量 问权值刚好等于x的前缀有多少个。
简单分析我们能得到无穷多个的情况的情况 考虑不是无穷个的情况 那么显然我们每循环一次都是要加上一个固定值的。
考试的时候我就那这一串数疯狂的模拟模拟到炸 可谓是非常的不明智。
进一步分析 我们发现每循环一次 由于我们0和1的数量的值都在变化 所以我们一个位置最多统计一次答案。
我们只需要判断某一个位置是否能对答案进行贡献即可. 有几种情况 写出来 画一下 就算出来了 还是很简单的 但是要注意 经过思考之后可以简化代码。
不要 不经过思考写一下不明智的代码.
[CF1303E](https://codeforces.com/contest/1303/problem/E)
这道题犯的错误是 连一个基本的dp模型都忘了 现在完全都是看道题就想贪心... 不太会的题要强行dp
这道题是 让我们把一个字符串分成两部分并在给定字符串中找到 且每个位置最多使用一次.
显然我们枚举一下间隔之后是 如何分配s 使得两部分都能匹配上 。
我当时采取是贪心 但是贪心并不正确因为不知道 对于一个点到底是选还是不选。
我们采用dp f[i][j][k]表示 匹配到了i 第一个串匹配到了j 第二个串匹配到了k是否合法这个状态即可解决上述对于一个位置到底是选还是不选的问题.
n^4 考虑优化一下这个dp 显然 我们可以把k省掉 变成 f[i][j]表示 第一个串匹配到了i 第二个串匹配到j的最大值即可.
[CF1301C]我也不知道为什么这道题我没想出来 苦恼 自己越来越笨了。
首先 我们知道对于一个序列怎么计算答案 我考虑 贪心的放1 但并非每次把区间分成原来的一半。
我们好像很难构造出来一种最大的情况 这个时候要倒着想!!!
考虑容斥 算不合法方案 发现超级好算 每连续一段的0 作为贡献来计算答案.
这个时候我们可以很简单的发现 0的段 越短越好 所以m个1 可以把序列分成m+1段 其中有一部分 长度为 (n-m)/(m+1) 还有一部分长度是(n-m)%(m+1);
这样计算即可 正难则反 正难则反啊.
[ATC Contest 155 F](https://atcoder.jp/contests/abc155/tasks/abc155_f)
这是那场比赛种最有意思也是 最难想出来的题目了 譬如我 想的是一脸懵逼.. 为什么我总是想不出来 。
这题绝了 神奇dfs 。题目是坐标轴上给出一些炸弹 炸弹有开有关 给出一些区间可以使一个区间内的炸弹翻转状态。
然后 问 是否存在解使得 所有炸弹都给关上并输出方案。区间翻转 线段树能做 暴力dp 但是我们不知道一个区间是否可以被修改的合法 也很难知道。
考虑 把区间操作该成单调操作 这是常规套路好吧 设出一个b数组 使得 b1^b2^...$b_{i-1}$=$a_i$
那么我们的区间操作 变成 在b数组上的单点操作了 最后还多出一个数字$b_{n+1}$来辅助我们。
对于一个区间 L 和 R 其实 就是把BL 和 $B_{R-1}$的状态给修改过来。
使得最后b数组全为0. 那么我们把 这么多条边给搞到图上 不难发现 我们每次只会修改两个点。
所以是偶数个1 才会有解 我们只需要操控一些边把 所有的点的状态变成0即可.
考虑一个联通块吧 考虑其有解 的时候 肯定是 两两相连的点使用这条边。
然后其他联通块是合法的,其实仔细思考这样随意找解的做法其实是正确的。但是我真的不会证明。
[CF1301 D](https://codeforces.com/contest/1301/problem/D)
此题 比较水但是考试的时候慌了 就没看题 自闭自闭自闭..
其实就是让你构造路径 然后 截图一下在图上构造一下即可 注意QQ的使用方法:其中有截图工具...
细节还挺多...
[ABC 156E](https://atcoder.jp/contests/abc156/tasks/abc156_e)
有一说一 我之所以补ABC的题因为我语文过差 长长不清醒 不知道自己在干嘛.总结 要认真啊。
题目意思是每个人每次可以移动一步 但是不能原地不动。
问k步之后房间的情况有多少种。
显然当k>=n-1时我们可以构造出来所有的情况如果对于情况多了一步我们显然可以中途浪费一步 多了两步那么来回再走一发即可.
显然不可能少步,所以这样的方案数显然位一个隔板法:C(n+n-1,n-1);
考虑k 显然上面的情况有些方案是不合法的。考虑减去,这容斥很白痴...
或者也可以dp不过dp的复杂度过高 所以考虑容斥了.
可以简单思考一下什么时候不合法 显然有 一个房间的人>k+1时一定不合法 此时 其他房间任意放。
这里是一个代表元容斥。不难发现这样的容斥是错误的 可能每一个房间的人数都是合法的 但是总体来看还是不合法的。
再次定义一种不合法的情况为有大于k个的空位我们发现对于一些空位小于k的话我们一定可以构造出相应的情况。
我们暴力枚举不合法情况然后进行容斥即可.值得一提的是 我终于知道我为什么A不了这道题了。
我写了一个假的容斥 我从 k+1~n-1这这件采用隔板法+容斥。考虑i个房间为空 此时多减去了一些不合法方案因为可能有i+1个房间是不合法的但是多减了。
通常情况下考虑加上去但是 我们并不能像普通容斥那个样子直接加上去因为我们不知道不合法的有多少了。引出一个重要结论。 ####中途进行容斥是错误的!
实际上我们可以直接算出来不合法的方案 这个地方也是隔板法的基本应用不再赘述。
说实话最近比赛有点难过 好像没有自信还是什么 什么题目都想不出来。
3-1的CF ABC 写完后开了E 发现挺水的 当时还有1h 我写了10min写完了故作聪明的把题目中的条件写反了(自己意识操控的。
可题目给的就是一个反着的 wa了两发 然后瞪眼1h 最终自闭离场。得到的经验如下。 #####做完题目后要再审一遍题! 同时这次的事故也警示我 wa的时候不要慌冷静的分析问题所在 而不是去盲目找错误。
原本5~6题的水平 硬生生变到了只做了3道题的水平。
3-1的ABC场 F题给出两圆心坐标及半径求两圆的交点 我发现这是一个计算几何的问题 无法用数学来解决 因为联立方程组用计算机实现过于困难。
还是需要补一发这种套路题目。
3-1 天下我有练习赛 T3 这道题我一直思索没有想到很好的方法实现。 性质很好挖掘 无非是次数最少且尽可能集中 但是第二个条件我始终无法满足。 我是考虑排序后每次扫到一个数字 看它和前一个的大小关系然后进行修改。 但这样很难使次数集中,又思考20min一直离不开这个思路我明白这是我目前最大的弊病 就是围绕着一两个思路不去思考其他的方向。 再推性质可以发现让尽可能的小的数字修改的越多 那么越集中。 但是我总不可能从大到小扫吧所以就一直无果了。 但是只要我考虑到 给数字分配位置 上述问题就迎刃而解了 这叫角度转移而不是原来的实时分配。 考虑到这个角度 我们考虑出现位置拥挤时 放到队列里 然后有位置可用的时候拿出来然后尽可能拿出来最晚放进去的就解决了上述问题。单调栈即可。 这道题并不算很难 但是却暴露出我最大的问题了。 ####觉得这个思路行不通的时候一定要快速更换思路 或者从另一个问题的角度看待问题从而解决问题。不能一直死磕一个角度 要灵活。
3-14 的CF 1325 E题 做到E题还剩下50分钟。我以为今天开局还行。。 但是由于当时不是很想思考了 所以就再没做出E F E题的犯错原因 没有认真理解题目意思 我明白题目在干什么 但是没有抓好题目的条件。 ####注意题目中的特定条件是非常关键的一环 而不是可忽略的 有的时候忽略了人会让你觉得问题十分不可做。 我就当时觉得非常不可做 想了20min钟无果 看了一眼F 然后走人了。 但其实E题有一个条件 每个数的因数不超过7个 这说明了什么?我当时以为是质因数类似的 所以没管。 因数不超过7个说明质因数最多有2个 因为3个质因数是有8个质因数。
所以我们发现每个数字除掉平方质因子之后形式 为 1 1,p 1,p,q 三种形式。
其中除掉平方质因子是很自然的事情因为要这个东西没啥用。考虑剩下这种数字怎么找答案。
显然我们可以转换成图论问题 1~1 1~p p~q之间连边 我们发现其实就是找图中的最小环。
形成环的话意味着每条边的质因子我们都用了 且每个质因子出现了偶数次。求最小环经典做法是floyd.
但是由于数据范围 这样做会T 我们祭出bfs求环 因为边权都是1嘛 可以发现正确性显然 复杂度\(n^2\)
看起来过不了 但是此时我们考虑一下复杂度的瓶颈 我们要从每个点bfs一遍 设m=\(\sqrt(max a_i)\)
那么对于一个p>m的质数我们没必要再跑一遍 p不可能跑到一个比m还大的质数上 不然 \(p\cdot q\)>\(m^2\) 所以复杂度nm 可以通过。
所以 通过这道题 题目的条件一定要分析清楚 不要盲目做题。并且get到了新技能bfs求最小环。
关于组合数又得到了一个小trick \(C(2n,n)=\sum_{k=0}^{n}C(n,k)\cdot C(n,k)\)
所以在求某一行组合数的平方和 也可以直接O(1)出解。
关于求幂级函数和 一般采用的是伯努利数来求 不过我不会。得到的小trick是可以列出方程。
\(\sum_{i=1}^{n}i^d\)对于这个东西求和 你会发现我们采用线性筛法复杂度为O(n).
但是当n巨大的时候就GG了。所以我们对d下手 当d较小<=500时我们采用列出方程。
\(\sum_{i=1}^{n}i^d=\sum_{i=1}^{d+1}v_in^i\)
可以发现我们找到d+1个n来填 再用GAUSS解出\(v_i\)即可。
3.23 CF R 84 D题又读错题辣 没理解清题目的条件直接想了一种做法最后wa+RE 自闭到底。
(还好E做出来了...不然真的血亏一波 F也没时间看了。
要仔细认真的读题 读题 读题。
今天的模拟赛被卡常了30 原因是输出过慢了。
输出的是一堆01串 直接printf运行很慢 标程是专程字符串再输出了 可见字符串一次性输出比一个一个输出快上很多 这点卡常技巧要记住哦。
输出的时候要看清输出的格式 横着输出的话不要竖着输出。
需要开long long的时候一定要仔细仔细再仔细的把该开的开全。
注意要严格计算空间限制 MLE相当于爆零了。
时间松的时候要精细实现 不然因为常数原因T掉真的很可惜。
一个卡常问题:重载运算符的时候 <什么的 类型是bool真的比int/long long快很多。
一个UB问题:b[++cnt]=cnt.这个在LINUX系统下是未定义行为 可能会导致一些莫名其妙的错误.