题目链接: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;
}