线段树 21pts 求助!
查看原帖
线段树 21pts 求助!
253608
Tx_Lcy楼主2022/9/14 19:52
#include<bits/stdc++.h>
using namespace std;
#define int long long
int const N=5e6+10;
int a[N];
struct Segment_Tree{
	#define ls (x<<1)
	#define rs (x<<1|1)
	#define mid ((l+r)>>1)
	bool c[N<<2];int le[N<<2],ri[N<<2],lazy[N<<2];
	inline void pushup(int x){
		c[x]=(c[ls] && c[rs] && ri[ls]<=le[rs]);
		le[x]=le[ls],ri[x]=ri[rs];
	}
	inline void build(int x,int l,int r){
		if (l==r){c[x]=1;le[x]=a[l];ri[x]=a[l];return;}
		build(ls,l,mid);build(rs,mid+1,r);
		pushup(x);
	}
	inline void pushdown(int x){
		le[ls]+=lazy[x],ri[rs]+=lazy[x];
		lazy[ls]+=lazy[x],lazy[rs]+=lazy[x];
		lazy[x]=0;
		pushup(x);
	}
	inline void update(int x,int l,int r,int ll,int rr,int v){
	    if (ll<=l && r<=rr){le[x]+=v,ri[x]+=v;lazy[x]+=v;return;}
	    pushdown(x);
	    if (ll<=mid) update(ls,l,mid,ll,rr,v);
	 	if (mid<rr) update(rs,mid+1,r,ll,rr,v);
	    pushup(x);
	}
	inline bool query(int x,int l,int r,int ll,int rr){
	    if (ll<=l && r<=rr) return c[x];
	    pushdown(x);
		bool flag=1;
	    if (ll<=mid && mid+1<=rr) flag&=(ri[ls]<=le[rs]);
	    if (ll<=mid) flag&=query(ls,l,mid,ll,rr);
	    if (mid<rr) flag&=query(rs,mid+1,r,ll,rr);
		return flag;
	}
}T;
signed main(){
    ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	int n,k;cin>>n>>k;
	for (int i=1;i<=n;++i) cin>>a[i];
    T.build(1,1,n);
    while (k--){
    	int opt;cin>>opt;
    	if (opt==1){
    		int l,r,x;cin>>l>>r>>x;r=min(r,n);
    		T.update(1,1,n,l,r,x);
		}else{
			int l,r;cin>>l>>r;r=min(r,n);
			if (T.query(1,1,n,l,r)) cout<<"Yes\n";
			else cout<<"No\n";
		}
	}
	return 0;
}
2022/9/14 19:52
加载中...