洛谷 AT_abc411_c [ABC411C] Black Intervals 题解
AT_abc411_c [ABC411C] Black Intervals 题解
写在前面的废话:这是本剧弱的第四篇题解了
正式开始解题。
1. 读题
题意其实挺清楚的:一排有 \(N\) 个格子,初始时所有格子均为白色。现在给出 \(Q\) 次修改和查询,问你黑色格子的数量。
举个例子:
样例:
5 7
2 3 3 5 1 5 2
- 全部是白色:

黑色区域数量:0。
- 第二个颜色反转。

黑色区域数量:1。
- 第3个颜色反转。

黑色区域数量:1。
- 第3个颜色反转。

黑色区域数量:1。
- 第5个颜色反转。

黑色区域数量:2。
- 第1个颜色反转。

黑色区域数量:2。
- 第5个颜色反转。

黑色数量:1。
- 第2个颜色反转。

黑色区域数量:1。
所以输出为
1
1
1
2
2
1
1
2. 解题思路
由于数据范围(\(1 \le N,Q \le 5×10^5\)),暴力(两层循环)肯定是过不了,我们可以考虑边读入变计算的方法,用布尔数组存下每一个格子的状态,然后进行判断。
3. 代码详解
- 变量定义
#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; //计数器,有多少个黑色的个子。
- 数据读入及判断
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;
}
以上就是全部题解了,再说几句废话
推荐一下我的其他题解
如果对你有帮助,点个赞再走吧!谢谢!
浙公网安备 33010602011771号