栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

2021辽宁省赛 I 完美主义 树状数组/暴力

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021辽宁省赛 I 完美主义 树状数组/暴力

Remember, Red, hope is good thing, mabye the best of things. And no good thing ever die.——肖申克的救赎


题目链接
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述
阿强采摘了一些苹果,并把他们分堆排成了一行,从左往右编号为第 1 … 푛 堆,其中第푖堆苹果有 a i a_i ai​个。
完美主义者阿珍看到这些苹果,觉得他们摆放的非常杂乱。她要求阿强进行如下的操作。
对某堆苹果进行调整:阿强将会将第푖堆苹果调整成 b i b_i bi​个;
对阿珍询问做出答复:其中每次询问表示为[푙, 푟],表示询问第푙堆到第푟堆之间的苹果数量是否满足 a l ≤ a l + 1 ≤ … ≤ a r − 1 ≤ a r a_lle a_{l+1} le …le a_{r-1} le a_r al​≤al+1​≤…≤ar−1​≤ar​,如果满足则称为完美。

输入描述
第一行两个整数n,q(1<=n,q<=3*10^5),表示苹果的堆数和操作的个数;
第二行n个整数表示 a i a_i ai​。
以下푞行,每行3个整数,第一个整数为opt;
若opt = 1,之后两个整数 i , b i i,b_i i,bi​表示将第푖堆苹果调整为 b i b_i bi​个;
若opt = 2,之后两个整数푙, 푟,表示对[푙, 푟]之间的苹果堆进行询问。(1<= a i , b i a_i,b_i ai​,bi​<=10^9)

输出描述:
输出一共푞行,每行一个 Yes 或者 No,表示每个询问对应区间是否完美。

输入
7 4
1 2 2 4 3 4 5
1 1 4
2 1 7
2 6 7
2 4 7
输出
No
Yes
No

队友A的想法:
先把这些数用a数组存起来,然后再用一个树状数组c表示每一个数对于前一个数是不是非递减,如果这个数大于等于前面的数,就记为0,否则记为-1。

1224345
0000-100

这样我们可以用树状数组实现logn的修改和查询,如果l到r是完美区间,则sum(r )-sum(l+1)=0。
但是因为我太菜了,一直WA…
然后队友B突然说这题过了,我们都很震惊,发现居然暴力就能过:D。。。。。
晚上回来终于把这题改过了,说明这个思路是没问题的
树状数组版

#include
using namespace std;
long long c[300005];
long long num[300005];
int n;
int lowbit(int x){
	return (x&(-x));
}
void update(int i,int val){
	 while(i<=n){
	 	c[i]+=val;
	 	i+=lowbit(i);
	 }
}
int sum(long long i){
	int ans=0;
	while(i>=1){
		ans+=c[i];
		i-=lowbit(i);
	}
	return ans;
}
int main(){
	int q,i;
	cin>>n>>q;
	for(i=1;i<=n;i++){
	    cin>>num[i];
		if(num[i]//如果一个数小于前一个数,就把它设为-1
			update(i,-1);
		}
	}
	for(i=1;i<=q;i++){
		int opt;
		long long a,b;
		cin>>opt>>a>>b;
		if(opt==1){
			num[a]=b;
			//更改一个数,要判断这个数和后面那个数!
		    if(b>=num[a-1]) {//这个数大于等于前一个数
		    	if(sum(a)-sum(a-1)==-1) update(a,1);
		    	//如果这个数原本小于前面的数,将-1改为0;如果这个数原本大于等于前面的数就不用改
			}
			else{//这个数小于前一个数
			if(sum(a)-sum(a-1)==0) update(a,-1);
			//如果这个数原本大于等于前面的数,将0改为-1,;如果这个数原本小于前面的数就不用改
			}
			if(num[a+1]>=b){//判断这个数的后一个数,同上。
				if(sum(a+1)-sum(a)==-1) update(a+1,1);
			}
			else{
				if(sum(a+1)-sum(a)==0) update(a+1,-1);
			}
			
		}
		else if(opt==2){
			int ans=sum(b)-sum(a);//计算a+1到b的区间和
			if(ans==0) cout<<"Yes"< 

暴力版

#include
using namespace std;
int main(){
	int n,q,l,r,opt;
	long long a[300005];
	cin>>n>>q;
	int i,j;
	for(i=1;i<=n;i++){
		cin>>a[i];
	}
	for(i=1;i<=q;i++){
		cin>>opt>>l>>r;
		if(opt==1)a[l]=r;
		
		else{
			for(j=l;j
				if(a[j]>a[j+1])break;
			}
			if(j==r)cout<<"Yes"< 

这道题告诉我们如果实在不会要勇敢的写暴力!!说不定就过了!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/890094.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号