比赛传送门
D
可以注意到,由于飞机中两个三个相同的数必须是相邻的,所以只用枚举一个数便可知道另一个三个相同的数是什么
接下来就该考虑如何分配后面两个对子:
对于一个点数,如果该点数有 $2$ 或 $3$ 张,那么该点数可以拿去凑到其中一对
(记这种情况的点数有 c2 个)
如果 $≥4$ 张,那么该点数可以自成两对或者是拿去凑到其中一对
(记这种情况的点数有 c4 个)
于是可以这样组合:
c2中自取不同的两对: c2*(c2-1)/2
c4中自取不同的两对: c4*(c4-1)/2
c2和c4中各取一对: c2*c4
c4中自取相同的两对: c4
在每次枚举三个相同的数时更新 c2 和 c4 即可快速计算
Code
1 | void solve(){ |
G
仔细观察可以注意到,对于一个顺子区间[l,r] 修改次数为$n$-该区间内数字的种类数(这里指在原数组内的)
点数最多1e9,用map存点数信息,由于我们最后只要计算区间内元素种类数,点数个数并不重要,我们将点数的最后一次出现的索引记录,便于后续给出操作方案
可以将map存储的信息转到 vector 容器中,便于我们查询
可以发现,区间端点为原先就有的数字为最优
利用双指针计算长度为 $n$ 的区间包含的最多元素种类数,同时记录最优区间的左端点,便于后续给出操作方案
目前已经可以给出最优操作次数了,就差给出操作方案:
用set记录最优区间中已经包含的数字,用vis数组记录这些数字最后一次出现的索引(因为只要保留一个,所以有最后一个索引也就够了)
遍历原数组,跳过vis数组中已经记录过的索引,这些位置不要动
记一个变量 $now$ 为当前要改成的数字,在遍历原数组的过程中,要跳过原数组中已经有的最优区间内的数字
Code
1 | void solve(){ |
说些什么吧!