洛谷--P4513--线段树--Sabrina--Sabrinadol

#include<cstring>
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define maxn 5000005 
using namespace std;
struct node{
 long long int l,r,f,v,lm,rm,mm;
}tree[maxn];
long long int n,m,x;
void update( int k)
{
	tree[k].v=tree[k*2].v+tree[k*2+1].v;
	tree[k].lm=max(tree[k*2].lm,tree[k*2].v+tree[k*2+1].lm);
	tree[k].rm=max(tree[k*2+1].rm,tree[k*2+1].v+tree[k*2].rm);
	tree[k].mm=max(tree[k*2].mm,max(tree[k*2+1].mm,tree[k*2].rm+tree[k*2+1].lm));
}
//建立一个线段树 
void creat(long long int x,long long int y,long long int k)
{
	tree[k].l=x;
	tree[k].r=y;
	if(x==y)
	{
		scanf("%lld",&tree[k].v); 
		tree[k].lm=tree[k].v;
		tree[k].rm=tree[k].v;
		tree[k].mm=tree[k].v;
		return ;
	}
	int mid=(x+y)/2;
	creat(x,mid,k*2);
	creat(mid+1,y,k*2+1);
	update(k);
}
void changing(long long int p,long long int num,long long int k)
{
	if(p==tree[k].l&&p==tree[k].r)
	{
		tree[k].v=num;
		tree[k].lm=num;
		tree[k].rm=num;
		tree[k].mm=num;
		return ;
	}
	int mid=(tree[k].l+tree[k].r)/2;
	if(p<=mid)
	changing(p,num,k*2);
	else
	changing(p,num,k*2+1);
	update(k);
}
node find(long long int l,long long int r,int k)
{
	int flag1=0,flag2=0;
	node left,right;
	if(l<=tree[k].l&&tree[k].r<=r)
	return tree[k];
	int mid=(tree[k].l+tree[k].r)/2;
	if(l<=mid)
	{
		left=find(l,r,k*2);
		flag1=1;
	}
	if(r>mid)
	{
		right=find(l,r,k*2+1);
		flag2=1;
	}
	if(flag1&&flag2)
	{
		node m;
		m.l=left.l;
		m.r=right.r;
		m.v=left.v+right.v;
		m.lm=max(left.lm,left.v+right.lm);
		m.rm=max(left.rm+right.v,right.rm);
		m.mm=max(left.mm,max(left.rm+right.lm,right.mm));
		return m;
	}
	if(flag1)
	return left;
	if(flag2)
	return right;
}
long long int a,b,c;
int flag;
int main()
{
//	freopen("truffle.in","r",stdin);
//	freopen("truffle.out","w",stdout);

	cin>>n>>m;
	creat(1,n,1);
	
//	for(int i=1;i<=10;i++)
//	cout<<tree[i].v<<" "<<endl;
	for(int i=1;i<=m;i++)
	{
		cin>>flag;
		if(flag==1)
		{
			scanf("%lld %lld",&a,&b);
			long long 	int tong;
			if(a>b)
			{
				tong=a;
				a=b;
				b=tong;
			}
			node kkfly=find(a,b,1);
			cout<<kkfly.mm<<endl;
		}
		else
		{
			scanf("%lld %lld",&a,&b);
			changing(a,b,1);
		}
	}
	fclose(stdin);
	fclose(stdout);
	return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值