社区讨论

萌新刚学线段树,20分求调

P1253扶苏的问题参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lo19w78q
此快照首次捕获于
2023/10/22 17:35
2 年前
此快照最后确认于
2023/11/02 17:52
2 年前
查看原帖
RT,我太菜力 思路:tagaddtagchange分别处理增加和改变,先下传改变再下传增加,改变时摧毁之前的所有标记

CPP
#include<bits/stdc++.h>
#include<unistd.h>
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define pii pair<int,int>
#define mp(a,b) make_pair(a,b)
#define endl '\n'
using namespace std;
const int N=3e6+1;
const ll INF=1e11+7;
struct Tree
{
	int lson,rson;
	ll sum,tagadd=0,tagchange=INF;	
}a[N];
ll A[N];
void pushup(int u)
{
	a[u].sum=max(a[a[u].lson].sum,a[a[u].rson].sum);
}
void pushdown(int u,int l,int r)
{
	if(a[u].tagadd==0&&a[u].tagchange==INF)return;
	int mid=l+r>>1;
	if(a[u].tagchange!=INF)
	{
		a[a[u].lson].tagadd=0;
		a[a[u].rson].tagadd=0;
		a[a[u].lson].tagchange=a[u].tagchange;
		a[a[u].rson].tagchange=a[u].tagchange;
		a[a[u].lson].sum=a[u].tagchange;
		a[a[u].rson].sum=a[u].tagchange;
	}
	a[a[u].lson].sum+=a[u].tagadd;
	a[a[u].rson].sum+=a[u].tagadd;
	a[u].tagadd=0; 
	a[u].tagchange=INF; 
} 
int t=1;
int x,y;
void build(int u,int l,int r)
{
	if(l==r)
	{
		a[u].sum=A[l];//单点,值等于它原本的值
		return ; 
	}
	int mid=l+r>>1;
	a[u].lson=++t;//开节点,建线段树 
	build(a[u].lson,l,mid);
	a[u].rson=++t;
	build(a[u].rson,mid+1,r); 
	pushup(u);
}
bool flag;//0改 1加法 
void update(int u,int l,int r,ll w)
{
	if(x<=l&&r<=y)
	{
		if(flag) 
		{
			a[u].tagadd+=w;
			a[u].sum+=w;
		}
		else
		{
			a[u].tagadd=0;
			a[u].tagchange=w; 
			a[u].sum=w;
		}
		return ;
	} 
	int mid=l+r>>1;
	pushdown(u,l,r);
	if(x<=mid)update(a[u].lson,l,mid,w);
	if(y>mid)update(a[u].rson,mid+1,r,w);
	pushup(u); 
} 
ll query(int u,int l,int r)//区间查询(从u号节点在l到r之间查询fl到rl的值) 
{
	ll ans=-INF;
	if(x<=l&&r<=y)
	{
		return a[u].sum;
	}
	pushdown(u,l,r);
	int mid=l+r>>1;
	if(x<=mid)
	{
		ans=max(ans,query(a[u].lson,l,mid));
	}
    if(y>mid)
	{
		ans=max(ans,query(a[u].rson,mid+1,r));
	}
    pushup(u);
    return ans;
} 
inline ll read()
{
	ll x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
int main()
{
	ll n=read(),m=read();
	for(int i=1;i<=n;i++) A[i]=read();
	build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		ll op=read();
		x=read(),y=read();
		if(op==3)
		{	
			ll ans=query(1,1,n);
			cout<<ans<<endl;
		}
		else
		{
			if(op==1) flag=0;
			if(op==2) flag=1;
			ll w=read();
			update(1,1,n,w);
		}
	}
	return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...