CF1055B 题解

CF1055B 题解

思路

其实就是一道用数组做的模拟题。

就用一个数组 \(a\) 记录第 \(i\) 根头发的长度,一个变量 \(ans\) 来记录目前捡的话要几秒钟,接下来就是要输入 \(a\) 数组,那其实也很简单,\(ans\) 就动态更新,如果前面一根头发不需要剪,而这根头发大于 \(l\),则 ans++,因为其实将 \(ans\) 转化一下就是求 \(a\) 数组中有几个连续区间使得区间内的所有数都大于 \(l\),所以要是 \(a_i>l\) 并且 \(a_{i-1}\leqslant l\),则会多出一个区间。

然后初始化完了就要开始进行 \(m\) 次操作:

  1. 要是第一个数为 \(0\),则直接输出 \(ans\)
  2. 要是第一个数是 \(1\),就要开始操作了:

首先,\(a_p=a_p+d\),然后就要开始更新 \(ans\),分为以下两种情况:

  1. 要是更新完的 \(a_p\) 大于 \(l\),并且 \(a_{p-1}\leqslant l,a_{p+1}\leqslant l\),则 \(a_p\) 为一个新的区间,因此 ans++
  2. 要是更新完的 \(a_p\) 大于 \(l\),并且 \(a_{p-1}>l,a_{p+1}>l\),则 \(a_p\) 让前面和后面的区间连在了一起(两个区间合二为一),因此 ans--

注意:上面两种情况都是原本的 \(a_p\) 小于等于 \(l\)

总结

  1. 模拟。
  2. 数组基础。
  3. 分类讨论。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n,m,l,ans,a[100005],x,p,d;
int main(){
	scanf("%lld %lld %lld",&n,&m,&l);
	for(int i=1; i<=n; i++){
		scanf("%lld",&a[i]);
		if(a[i-1]<=l&&a[i]>l) ans++;//a[i]要剪,且a[i-1]不需要剪,则a[i]多创造出来了一个区间。 
	}
	while(m--){//m次操作。 
		scanf("%lld",&x);
		if(x==0) printf("%lld\n",ans);//直接输出答案,头发全都剪完了。 
		else{//某根头发又神经质的长长了。 
			scanf("%lld %lld",&p,&d);
			a[p]+=d;//更新。 
			if(a[p]-d<=l){//原本是不需要剪的才可以,因为它如果原本就已经要剪的话它不管怎么长都是要剪的,而且那样ans不用变。 
				if(a[p]>l&&a[p-1]<=l&&a[p+1]<=l) ans++;//前后都是不需要剪的,所以这根头发创建了一个新区间。 
				if(a[p-1]>l&&a[p]>l&&a[p+1]>l) ans--;//前后都是要剪的,而因为原本a[p]不需要减,不属于前后两个区间,而现在,它不仅属于两个区间了,还把两个区间连起来了,所以区间数减少1。 
			}
		}
	}
	return 0;
}
posted @ 2025-01-29 15:33  naroto2022  阅读(12)  评论(0)    收藏  举报