首页 > 其他分享 >[JOI 2013 Final]彩灯

[JOI 2013 Final]彩灯

时间:2024-10-10 15:46:03浏览次数:1  
标签:子段 int 反转 s1 s0 JOI Final 2013

[JOI 2013 Final]彩灯

题意

给出一个 \(01\) 序列,可以把一段区间反转。

求反转后序列最长的交替子段,即 \(010101 \ldots\) 或 \(101010 \ldots\)。

思路

首先发现一个性质,反转的一定是一段交替子段。

因为反转不交替子段对答案的贡献不优。

枚举反转哪一段交替子段,统计左右两边的子段和它连起来的长度,取最大值即可。

具体实现时维护从某个数向前和向后的连续 \(0101\) 长度,连续 \(1010\) 长度。

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;

int n, a[N], ans;
int p0[N], p1[N], s0[N], s1[N];

int main() {
	freopen("deng.in", "r", stdin);
	freopen("deng.out", "w", stdout);
	
	cin >> n;
	for (int i = 1; i <= n; i ++)
		cin >> a[i];
	
	for (int i = 1; i <= n; i ++) {
		if (a[i] != a[i - 1]) {
			p0[i] = p0[i - 1] + 1;
			p1[i] = p1[i - 1] + 1;
		}	else {
			p0[i] = 1;
			p1[i] = 1;
		}
	}
	for (int i = 1; i <= n; i ++) {
		if (a[i] == 1) p0[i] = 0;
		else p1[i] = 0;
	}
	
	for (int i = n; i >= 1; i --) {
		if (a[i] != a[i + 1]) {
			s0[i] = s0[i + 1] + 1;
			s1[i] = s1[i + 1] + 1;
		} else {
 			s0[i] = 1;
			s1[i] = 1;	
		}
	}
	for (int i = 1; i <= n; i ++) {
		if (a[i] == 1) s0[i] = 0;
		else s1[i] = 0;
	}
	
	for (int i = 1; i <= n; i ++) {
		if (i + s0[i + 1] <= n && a[i + s0[i + 1]] == 0) 
			ans = max(ans, p0[i] + s0[i + 1] + s0[i + s0[i + 1] + 1]);
		if (i + s0[i + 1] <= n && a[i + s0[i + 1]] == 1)
			ans = max(ans, p0[i] + s0[i + 1] + s1[i + s0[i + 1] + 1]);
		if (i + s1[i + 1] <= n && a[i + s1[i + 1]] == 0)
			ans = max(ans, p1[i] + s1[i + 1] + s0[i + s1[i + 1] + 1]);
		if (i + s1[i + 1] <= n && a[i + s1[i + 1]] == 1)
			ans = max(ans, p1[i] + s1[i + 1] + s1[i + s1[i + 1] + 1]);
		ans = max(ans, p0[i] + s1[i + 1]);
		ans = max(ans, p1[i] + s0[i + 1]);
	}
	
	cout << ans << "\n";
	return 0;
}

标签:子段,int,反转,s1,s0,JOI,Final,2013
From: https://www.cnblogs.com/maniubi/p/18456507

相关文章

  • [JOI 2013 Final]JOIOI 塔
    [JOI2013Final]JOIOI塔题意给出一个由\(\text{JOI}\)组成的字符串,可从中取出一些子序列。求最多取出多少\(\text{IOI}\)和\(\text{JOI}\)。思路若答案\(x\)可行,则所有\(y<x\)均可行,若答案\(x\)不可行,则所有\(y>x\)均不可行。这样就可以可行性二分。考虑如......
  • [JOI 2013 Final]现代豪宅
    [JOI2013Final]现代豪宅题意给出一个\(n\timesm\)的网格图,每两个格子之间有一扇门。初始上下方向的门都是开着的,左右方向的门是关着的。有一些格子有按钮,可以把打开的门关上,关上的门打开。走一步需要一秒,按按钮需要一秒,求从\((1,1)\)到达\((n,m)\)的最小步数。思路......
  • [JOI 2013 Final]搭乘 IOI 火车
    [JOI2013Final]搭乘IOI火车题意给出两个由\(\text{OI}\)组成的字符串\(S,T\)。可以删除每个字符串的前缀和后缀。每次从剩下部分的第一位取出一个字符放到新的字符串中。要求新字符串必须以\(\text{I}\)开头结尾,相同的字符不能相邻,求新字符串的最大长度。思路定义......
  • Guava中的Joiner和Splitter
    目录Guava介绍Joinerlist转stringmap转string处理嵌套集合处理null值Splitterstring转liststring转map多个拆分符输出代码Guava介绍Guava是Google开发的一个开源Java库,提供一系列核心功能增强Java的标准库。它包含许多有用的工具和集合类,使Java开发更加高效,代码更加......
  • gjoi 2024.10.9
    当天在家里躺尸看t1过不了就去睡觉了,还好没写卡场Round哦/cf怎么有人吃错了一整盒退高烧药啊/wqT1游戏升级考虑有多少\(x\in[1,n]\)满足\(b_1+\lfloor\frac{a_1}{x}\rfloor=b_2+\lfloor\frac{a_2}{x}\rfloor\),直接对下取整做整除分块即可。gjoj卡常所以开longl......
  • [ZJOI2008] 骑士
    \(基环树DP\)https://www.luogu.com.cn/problem/P2607\(将基环树上面的环破开成树就能进行如同《没有上司的舞会》的树形DP\)\(没有上司的舞会:\)https://www.luogu.com.cn/problem/P1352\(具体实现困难之处在于如何破环成树,其实只需要主要到对于树上的一个环,将环上的两个节......
  • JOI Open 2018
    T1BubbleSort2题意:给定一个长度为\(n\)的序列\(a\),进行\(q\)次修改,第\(i\)次将第\(x_i\)个元素的值修改为\(y_i\)。对于每次操作后,你都需要求出,如果此时对序列进行冒泡排序,需要多少次冒泡才能完成排序。\(n\le5\times10^5\)。序列有序意味着,每个数前面都没......
  • mysql join语法解析
     MySQL支持以下JOIN语法用于SELECT语句和多表DELETE和UPDATE语句中的table_references部分:table_references:查询中涉及的一个或多个表的引用,可以是简单表名或JOIN表达式的组合。escaped_table_reference[,escaped_table_reference]...escaped_table_ref......
  • 了解final关键字在Java并发编程领域的作用吗?
    在Java并发编程领域,final关键字扮演着一个至关重要的角色。虽然很多同学熟悉final用于修饰变量、方法和类的基本用法,但其在并发环境中的应用和原理却常常被忽视。final关键字不仅仅是一个简单的修饰符,它在多线程编程中确保对象状态的可见性和不变性,这对于构建线程安全的应用至关重......
  • Codeforces Round 977 (Div. 2, based on COMPFEST 16 - Final Round)
    目录写在前面A签到B贪心,枚举C1贪心C2贪心,枚举DDPE1/E2Kruscal重构树,树上背包写在最后写在前面补题地址:https://codeforces.com/contest/2021。上大分失败呃呃呃呃我不要上班呜呜A签到考虑仅有三个数\(a,b,c(a<b<c)\)时最优操作,手玩下发现最优操作顺序一定是......