洛谷 AT_abc411_c [ABC411C] Black Intervals 题解

AT_abc411_c [ABC411C] Black Intervals 题解

写在前面的话:这是本剧弱的第四篇题解了

正式开始解题。

1. 读题

题意其实挺清楚的:一排有 \(N\) 个格子,初始时所有格子均为白色。现在给出 \(Q\) 次修改和查询,问你黑色格子的数量。
举个例子:
样例:

5 7
2 3 3 5 1 5 2
  1. 全部是白色:

黑色区域数量:0。

  1. 第二个颜色反转。

黑色区域数量:1。

  1. 第3个颜色反转。

黑色区域数量:1。

  1. 第3个颜色反转。

黑色区域数量:1。

  1. 第5个颜色反转。

黑色区域数量:2。

  1. 第1个颜色反转。


黑色区域数量:2。

  1. 第5个颜色反转。

黑色数量:1。

  1. 第2个颜色反转。

黑色区域数量:1。

所以输出为

1
1
1
2
2
1
1

2. 解题思路

由于数据范围(\(1 \le N,Q \le 5×10^5\)),暴力(两层循环)肯定是过不了,我们可以考虑边读入变计算的方法,用布尔数组存下每一个格子的状态,然后进行判断。

3. 代码详解

  1. 变量定义
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
bool col[N];//用于存储每一个格子的状态。
int n,q,a;//与题目中的意思相同
//n:n 个格子
//q:q 次查询、修改。 
//a:每一次修改颜色的格子编号。
int cnt; //计数器,有多少个黑色的个子。
  1. 数据读入及判断
int main(){
	cin>>n>>q;
	while(q--){//有 n 次修改和查询。
		cin>>a;
		col[a]=!col[a];//黑变白,白变黑(取反)。
		if(col[a]){//如果第 a 个是黑色
			if(!col[a-1]&&!col[a+1]) cnt++;  //如果这个黑色的个子左右两边都是白色格子,就相当于增加了一个黑色格子(不理解的话看一看上面的样例)
			else if(col[a-1]&&col[a+1]) cnt--;//同理,如果这个黑色的个子左右两边都不是白色格子,就相当于减少了一个黑色格子
		}
		else{//如果第 a 个是白色
			if(!col[a-1]&&!col[a+1]) cnt--;  ////同理,如果这个白色的个子左右两边都是白色格子,就相当于减少了一个黑色格子
			else if(col[a-1]&&col[a+1]) cnt++;//同理,如果这个白色的个子左右两边都不是白色格子,就相当于增加了一个黑色格子。
		}
		cout<<cnt<<'\n';
	}
	return 0;
}

4. AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
bool col[N];
int n,q,a;
int cnt; 
int main(){
	cin>>n>>q;
	while(q--){
		cin>>a;
		col[a]=!col[a];
		if(col[a]){
			if(!col[a-1]&&!col[a+1]) cnt++;  
			else if(col[a-1]&&col[a+1]) cnt--;
		}
		else{
			if(!col[a-1]&&!col[a+1]) cnt--;  
			else if(col[a-1]&&col[a+1]) cnt++;
		}
		cout<<cnt<<'\n';
	}
	return 0;
}

以上就是全部题解了,再说几句废话
推荐一下我的其他题解


如果对你有帮助,点个赞再走吧!谢谢!

posted @ 2025-07-15 07:54  sunhy2012  阅读(114)  评论(0)    收藏  举报