思路讲解
其实还是挺简单的,不难,就是要分类讨论一下
前面搞着搞着搞错了,其实cnt→fi才是我们要加的
就是如果说我们不知道怎么排序或者什么,我们可以直接将答案算出来,取最大的答案就行了
1 | lans -= 1; // 先不管我们这个要做第二个操作的联通块 |
AC代码
AC
https://codeforces.com/contest/2063/submission/305604041
1 | // Problem: C. Remove Exactly Two |
其实还是挺简单的,不难,就是要分类讨论一下
前面搞着搞着搞错了,其实cnt→fi才是我们要加的
就是如果说我们不知道怎么排序或者什么,我们可以直接将答案算出来,取最大的答案就行了
1 | lans -= 1; // 先不管我们这个要做第二个操作的联通块 |
AC
https://codeforces.com/contest/2063/submission/305604041
1 | // Problem: C. Remove Exactly Two |
我们将不匹配的位置分类,发现最多只有四类,ab 分别是 00*,* 01*,* 10*,* 11 ,任意
两个不同种类不匹配的话,我们一定可以交换其中的某一位 0 和 1 使之两两匹配,
其他的没什么特殊的,我们发现四种情况全部都可以选择其他另外一种情况抵消。
那么问题就来到了怎么样抵消的问题上
我们一定可以交换其中的某一位 0 和 1 使之两两匹配,那么我
们就只看最多的一类不匹配的位置的数量有没有超过总数的一半即可。
如果超过就超过的部分反置,其余匹配,否则一定存在一种分配方式使之匹配后至多
仅剩一个。
官解的匹配方式是这样的,但我相信这个分类讨论大抵是没那么容易想到的,那我们有没有一种策略去匹配不出错那?
用大的去匹配次大的
https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75564916
1 | priority_queue<ll> pq; |
用大的去匹配小的
https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75565204
1 | priority_queue<ll> pq; |
似乎都会出问题,这些贪心策略都有瑕疵(见以下hack数据3,5,7,13)
1 | 28 5 6 |
有些人~~(我)~~可能觉得3,5,7,13根本无法消除(无法完全通过交换消除),通过交换最终会剩余2
但实际上是可以的,只不过比较复杂,需要通过分段的方法消除,具体见下

AC
https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75568259
1 | // Problem: 小L的位运算 |
哈哈,不知道还可以这样分段消除,还以为题目出问题了,我太菜了

倒过来找,不断的找树状数组上第pi个空位
这样做是对的原因是前面的被占的都是后来者,你是先来的,所以你只用管空白位置,完全不用管被占的位置
AC
https://atcoder.jp/contests/abc392/submissions/62634320
1 | // Problem: F - Insert |
为什么这道题目可以用类似于双指针的东西做出来?
其实有点类似于我最早的思路,就是已经合并过的就不管了。
不过他是以边为主视角的,这个还是比较新颖的,我之前的都是以块为主视角的,但块存在自环,重边,没边等等情况,总之肯定没有以边为主视角方便。

https://atcoder.jp/contests/abc392/submissions/62618534
1 | #include <bits/stdc++.h> |
直接遍历还是有风险,合并还是要用dsu
1 | // Problem: E - Cables and Servers |
AC
https://vjudge.net/solution/58198800
1 | // Problem: A/B |