线段树部分分求调
查看原帖
线段树部分分求调
615490
lcy_123楼主2023/10/18 19:17

做法是存每个区间的最左,最右的值和答案,合并区间的时候判断是否为单调递增

#include<bits/stdc++.h>
#define int long long
const int MAXN=1000005;
using namespace std;
int n,k,a[MAXN];
struct node
{
	int ans,l,r,lazy_tag;
}tre[MAXN*4];
inline int ls(int x){return x*2;}
inline int rs(int x){return x*2+1;}
void push_up(int pos)//
{
	if(tre[ls(pos)].r<=tre[rs(pos)].l&&tre[ls(pos)].ans&&tre[rs(pos)].ans)
		tre[pos].ans=1;
	else 
		tre[pos].ans=0;
	tre[pos].l=tre[ls(pos)].l;
	tre[pos].r=tre[rs(pos)].r;
}
void build(int l,int r,int pos)//
{
	if(l==r)
	{
		tre[pos].ans=1;
		tre[pos].l=tre[pos].r=a[l];
		return ;
	}
	int mid=(l+r)/2;
	build(l,mid,ls(pos));
	build(mid+1,r,rs(pos));
	push_up(pos);
}
void push_down(int pos)//
{
	tre[ls(pos)].lazy_tag+=tre[pos].lazy_tag;
	tre[rs(pos)].lazy_tag+=tre[pos].lazy_tag;
	tre[ls(pos)].l+=tre[pos].lazy_tag;
	tre[rs(pos)].r+=tre[pos].lazy_tag;
	tre[pos].lazy_tag=0;
}
void update(int dl,int dr,int l,int r,int pos,int x)
{
	push_down(pos);
	if(dl<=l&&r<=dr)
	{
		tre[pos].lazy_tag+=x;
		tre[pos].l+=x;
		tre[pos].r+=x;
		return ;
	}
	int mid=(l+r)/2;
	if(dl<=mid)update(dl,dr,l,mid,ls(pos),x);
	if(dr>mid)update(dl,dr,mid+1,r,rs(pos),x);
	push_up(pos);
}
int query(int dl,int dr,int l,int r,int pos)
{
	push_down(pos);
	if(dl<=l&&r<=dr)return tre[pos].ans;
	int mid=(l+r)/2;
	if(dl<=mid&&dr>mid)
	{
		int s1=query(dl,dr,l,mid,ls(pos));
		int s2=query(dl,dr,mid+1,r,rs(pos));
		return (s1&&s2&&tre[ls(pos)].r<=tre[rs(pos)].l);
	}
	if(dl<=mid)return query(dl,dr,l,mid,ls(pos));
	if(dr>mid)return query(dl,dr,mid+1,r,rs(pos));
}
signed main()
{
	cin>>n>>k;
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	build(1,n,1);
	for(int i=1;i<=k;i++)
	{
		int op,l,r;
		scanf("%lld%lld%lld",&op,&l,&r);
		if(r>n)r--;
		if(op==1)
		{
			int x;
			scanf("%lld",&x);
			update(l,r,1,n,1,x);
		}
		else
		{
			if(query(l,r,1,n,1))printf("Yes\n");
			else printf("No\n");
		}
	}
} 
2023/10/18 19:17
加载中...