传送门


首先显然的是可以一开始先染好再做、每个点只会被染一次、最后只剩下两种颜色。

接下来是结论时间:序列可以反转的充要条件是除了首尾的极大颜色连通块以外其他极大颜色连通块长度为偶数。


证明充分性:考虑归纳。

如果序列中有\(3\)个极大颜色连通块且中间的连通块长度为偶数,那么先将两端的颜色块折成\(1\),然后沿着中间块的中线对折,然后把较大的块折成\(1\)即可满足条件。

如果序列中有\(x>3\)个极大颜色连通块,则把尾部的极大颜色连通块长度折成\(1\)然后沿着倒数第二个颜色块的中线对折,可以得到一个有\(x-1\)个极大颜色连通块的局面。

由归纳可知假设成立。


证明必要性:仍然考虑归纳。

如果序列中有\(1\)个非首尾极大颜色连通块长度为奇数,那么无论如何这个奇数的连通块和与其相邻的连通块无法被对折,所以显然无解。

如果序列中有\(\geq 2\)个非首尾长度为奇数的极大颜色连通块,则如果进行折叠,显然不会使这样的连通块数量减少为\(0\)。

由归纳可知假设成立


与上面的结论等价的结论是:同色连通块的起始位置的奇偶性相同。

这样我们枚举每一种颜色,再枚举其起始位置的奇偶性,对于一个原序列中这样的非首尾极大连通块,如果不满足条件就尽可能向前后拓展。最后维护一下非当前位置的元素中出现次数最多的颜色就可以了。

复杂度不难做到\(O(n)\)。

#include<bits/stdc++.h>
using namespace std; int read(){
int a = 0; char c = getchar(); while(!isdigit(c)) c = getchar();
while(isdigit(c)){a = a * 10 + c - 48; c = getchar();}
return a;
} const int _ = 1e6 + 7; vector < int > pos[_]; int arr[_] , pot[_] , sz[_] , MX , N , M; void del(int x){if(!--sz[pot[x]] && pot[x] == MX) --MX; ++sz[--pot[x]];}
void add(int x){--sz[pot[x]]; ++sz[++pot[x]];} int main(){
N = read(); M = read(); if(M == 1){puts("0"); return 0;}
for(int i = 1 ; i <= N ; ++i){++pot[arr[i] = read()]; pos[arr[i]].push_back(i);}
for(int i = 1 ; i <= M ; ++i){++sz[pot[i]]; MX = max(MX , pot[i]);}
for(int i = 1 ; i <= M ; ++i){
int ans = 1e9 , p = 0 , q , now , pre = MX , S = pos[i].size(); --sz[pot[i]]; while(!sz[MX]) --MX; now = MX; while(p < S){
q = p; while(q < S && pos[i][q] - pos[i][p] == q - p) ++q;
if(!(pos[i][p] & 1)) del(arr[pos[i][p] - 1]);
if(pos[i][q - 1] != N && (pos[i][q - 1] & 1)) del(arr[pos[i][q - 1] + 1]);
p = q;
}
ans = min(ans , N - pot[i] - MX); MX = now; p = 0;
while(p < S){
q = p; while(q < S && pos[i][q] - pos[i][p] == q - p) ++q;
if(!(pos[i][p] & 1)) add(arr[pos[i][p] - 1]);
if(pos[i][q - 1] != N && (pos[i][q - 1] & 1)) add(arr[pos[i][q - 1] + 1]);
p = q;
} p = 0;
while(p < S){
q = p; while(q < S && pos[i][q] - pos[i][p] == q - p) ++q;
if(pos[i][p] != 1 && (pos[i][p] & 1)) del(arr[pos[i][p] - 1]);
if(pos[i][q - 1] != N && !(pos[i][q - 1] & 1)) del(arr[pos[i][q - 1] + 1]);
p = q;
}
printf("%d\n" , min(ans , N - pot[i] - MX)); p = 0; MX = pre; ++sz[pot[i]];
while(p < S){
q = p; while(q < S && pos[i][q] - pos[i][p] == q - p) ++q;
if(pos[i][p] != 1 && (pos[i][p] & 1)) add(arr[pos[i][p] - 1]);
if(pos[i][q - 1] != N && !(pos[i][q - 1] & 1)) add(arr[pos[i][q - 1] + 1]);
p = q;
}
}
return 0;
}

LOJ2336 JOI2017 绳 贪心、构造的更多相关文章

  1. 贪心+构造 Codeforces Round #277 (Div. 2) C. Palindrome Transformation

    题目传送门 /* 贪心+构造:因为是对称的,可以全都左一半考虑,过程很简单,但是能想到就很难了 */ /************************************************ ...

  2. 贪心/构造/DP 杂题选做

    本博客将会收录一些贪心/构造的我认为较有价值的题目,这样可以有效的避免日后碰到 P7115 或者 P7915 这样的题就束手无策进而垫底的情况/dk 某些题目虽然跟贪心关系不大,但是在 CF 上有个 ...

  3. 贪心/构造/DP 杂题选做Ⅱ

    由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...

  4. 贪心/构造/DP 杂题选做Ⅲ

    颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...

  5. Codeforces Round #301 (Div. 2)(A,【模拟】B,【贪心构造】C,【DFS】)

    A. Combination Lock time limit per test:2 seconds memory limit per test:256 megabytes input:standard ...

  6. Codeforces 1082D Maximum Diameter Graph (贪心构造)

    <题目链接> 题目大意:给你一些点的最大度数,让你构造一张图,使得该图的直径最长,输出对应直径以及所有的边. 解题分析:一道比较暴力的构造题,首先,我们贪心的想,要使图的直径最长,肯定是尽 ...

  7. hdu 4982 贪心构造序列

    http://acm.hdu.edu.cn/showproblem.php?pid=4982 给定n和k,求一个包含k个不相同正整数的集合,要求元素之和为n,并且其中k-1的元素的和为完全平方数 枚举 ...

  8. Codeforces Round #335 (Div. 2) D. Lazy Student 贪心+构造

    题目链接: http://codeforces.com/contest/606/problem/D D. Lazy Student time limit per test2 secondsmemory ...

  9. URAL 1995 Illegal spices 贪心构造

    Illegal spices 题目连接: http://acm.timus.ru/problem.aspx?space=1&num=1995 Description Jabba: Han, m ...

随机推荐

  1. Java中 / 和 %

    Java中 / 和 % 每天积累一些 Java 的知识点,补充自己的不足. 今天在刷面试题的碰到 % ,一下子还真想不起来这个运算符的作用,赶紧重温一下,这里我写了个小代码来体现 / 和 % 的区别. ...

  2. 人生物语——哲海拾贝

         如今的这个社会,物欲横流.纸醉金迷.浮躁不安是这个时代的主旋律,在这样一个浮华年代的大染缸里,每个人内心都有那么一颗浮躁不安分的种子,或许它才开始发芽,或许它已经占据了你的心灵,人生当中追求 ...

  3. Reactive-MongoDB 异步 Java Driver 解读

    一.关于 异步驱动 从3.0 版本开始,MongoDB 开始提供异步方式的驱动(Java Async Driver),这为应用提供了一种更高性能的选择.但实质上,使用同步驱动(Java Sync Dr ...

  4. NBU恢复数据库数据文件报错RMAN-06091

    RMAN-06091: no channel allocated for maintenance (of an appropriate type) 一.错误信息 报错信息如下 Starting res ...

  5. The Preliminary Contest for ICPC Asia Shenyang 2019 H. Texas hold'em Poker

    题目链接:https://nanti.jisuanke.com/t/41408 题目意思很简单,就是个模拟过程. #include <iostream> #include <cstr ...

  6. IDEA中如何导入一个maven项目并配置相关设置

    导入一个maven项目参照如下链接 https://jingyan.baidu.com/article/b0b63dbf0c0ac04a49307078.html 要想启动这个导入的项目目前我所接触到 ...

  7. 201871010118-唐敬博《面向对象程序设计(Java)》第四周学习总结

    博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.co ...

  8. Java多线程编程核心技术-第6章-单例模式与多线程-读书笔记

    第 6 章 单例模式与多线程 本章主要内容 如何使单例模式遇到多线程是安全的.正确的. 6.1 立即加载 / “饿汉模式” 什么是立即加载?立即加载就是使用类的时候已经将对象创建完毕,常见的实现办法就 ...

  9. nginx 其他配置语法

    1.nginx 缓冲区配置 2.跳转重定向 3.头信息 4.超时 location / { proxy_pass http://127.0.0.1:8080;(代理跳转url) proxy_redir ...

  10. linux 指定用户 启动 程序

    sudo -H -u {username} /bin/bash -c "python test.py &" "&"  后台运行指令 本人亲测可用 ...