Another Query Problem

题目链接:Another Query Problem


我们一直用线段树维护差分即可,区间数字一样代表什么呢?

那就是差分序列的 [l+1,r]都为0,所以线段树维护区间最值即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n,q,mi[N<<2],mx[N<<2],lazy[N<<2],a[N];
inline void push_down(int p){
	if(!lazy[p])	return ;
	mi[p<<1]+=lazy[p],mx[p<<1]+=lazy[p],lazy[p<<1]+=lazy[p];
	mi[p<<1|1]+=lazy[p],mx[p<<1|1]+=lazy[p],lazy[p<<1|1]+=lazy[p];
	lazy[p]=0;
}
void change(int p,int l,int r,int ql,int qr,int v){
	if(l==ql&&r==qr){mx[p]+=v,mi[p]+=v,lazy[p]+=v; return ;}
	int mid=l+r>>1;	push_down(p);
	if(qr<=mid)	change(p<<1,l,mid,ql,qr,v);
	else if(ql>mid)	change(p<<1|1,mid+1,r,ql,qr,v);
	else change(p<<1,l,mid,ql,mid,v),change(p<<1|1,mid+1,r,mid+1,qr,v);
	mx[p]=max(mx[p<<1],mx[p<<1|1]),mi[p]=min(mi[p<<1],mi[p<<1|1]);
}
int ask(int p,int l,int r,int ql,int qr,int k){
	if(l==ql&&r==qr)	return k?mx[p]:mi[p];
	int mid=l+r>>1;	push_down(p);
	if(qr<=mid)	return ask(p<<1,l,mid,ql,qr,k);
	else if(ql>mid)	return ask(p<<1|1,mid+1,r,ql,qr,k);
	else{
		if(k) return max(ask(p<<1,l,mid,ql,mid,k),ask(p<<1|1,mid+1,r,mid+1,qr,k));
		else return min(ask(p<<1,l,mid,ql,mid,k),ask(p<<1|1,mid+1,r,mid+1,qr,k));
	}
}
inline void upd(int l,int r,int a,int b){
	change(1,1,n,l,l,a);	if(l+1<=r) change(1,1,n,l+1,r,b);
	if(r<n)	change(1,1,n,r+1,r+1,-a-b*(r-l));
}
inline int calc(int l,int r){
	if(l==r)	return 1;
	int mi=ask(1,1,n,l+1,r,0),mx=ask(1,1,n,l+1,r,1);
	return (mi==mx&&mi==0);
}
signed main(){
	cin>>n>>q;
	for(int i=1,op,l,r,a,b;i<=q;i++){
		scanf("%lld %lld %lld",&op,&l,&r);
		if(op==1)	printf("%lld\n",calc(l,r));
		else scanf("%lld %lld",&a,&b),upd(l,r,a,b);
	}
	return 0;
}
发布了809 篇原创文章 · 获赞 246 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/105212059