Maximum continuous segment and sub-segment tree thinking ----- range

Given the number of columns of length N A, and M instructions, each instruction may be either of the following:

1, "1 xy", the query interval [x, y] is the maximum continuous and sub-segment, i.e. maxx≤l≤r≤y {Σri = lA [i]}.

2, "2 xy", the A [x] into y.

For each query command, output a integer answer.

Input format
of the first row two integers N, M.

The second row of the N integers A [i].

Next, 3 M lines each integers k, x, y, k = 1 indicates that the query (in this case, if x> y, swap the x, y), k = 2 represents a modification.

Output format
output represents an integer answer for each query command.

Each answer per line.

Data range
N≤500000, M≤100000
input sample:
. 5. 3
. 1. 4. 5 2 -3
. 1. 3 2
2 2-1
. 1. 3 2
Output Sample:
2
-1

Analysis:
We need to maintain the four information
1. The maximum prefix and
2. Maximum suffix and
3. The maximum continuous sub-section and
4 sections and
operate 4 well maintained.
3 us,
if asked just left interval interval so simple is the biggest sub-segment of the left section and
if the interval just ask you very simply in the right range is the maximum range of the right field and
if asked about sub-interval interval, then it is left the maximum range of suffixes and prefixes + Right and maximum range of
three to take max.
stresses 1 and 2 tell
if the interval just ask a very simple prefix in the left section is the largest section of the left and
if the query interval just the right intervals was simply the right range the maximum and suffix.
If the query interval coverage of the left section and there is also the right range, then that is the largest prefix interval left interval and + the right intervals and
if the inquiry section covers the right range and there is also a left section, then that is the right section of the zone and + the maximum range of the prefix left and
the four take max



#include<bits/stdc++.h>
using namespace std;
const int N=5e5+1000;
int n,m,x,y;
int a[N];
struct Node
{
	int l,r; //区间左右端点 
	int sum;//区间和 
	int lmax;//最大前缀和 
	int rmax;//最大后缀和 
	int tmax;//最大连续子段和 
}tr[N<<4]; 
void push_up(Node &u,Node &l,Node &r)
{
	u.sum=l.sum+r.sum;
	u.lmax=max(l.lmax,l.sum+r.lmax);
	u.rmax=max(r.rmax,r.sum+l.rmax);
	u.tmax=max(max(l.tmax,r.tmax),l.rmax+r.lmax);
}
void push_up(int u)
{
	push_up(tr[u],tr[u<<1],tr[u<<1|1]);
 } 
 void build(int u,int l,int r)
 {

 	if(l==r)
 	{
 		tr[u]={l,r,a[r],a[r],a[r],a[r]};
 		return ;
	}
	int mid=l+r>>1;
	tr[u]={l,r};
	build(u<<1,l,mid);
	build(u<<1|1,mid+1,r);
	push_up(u);
	
 }
void  update(int u,int x,int v)
 {
 	if(tr[u].l==tr[u].r)
 	{
 		tr[u]={x,x,v,v,v,v};
 		return ;
	}
	int mid=tr[u].l+tr[u].r>>1;
	if(x<=mid) update(u<<1,x,v);
	else update(u<<1|1,x,v);
	push_up(u);
 }
 Node query(int u,int l,int r)
 {
 	if(l<=tr[u].l&&r>=tr[u].r) return tr[u];
 	int mid=tr[u].l+tr[u].r>>1;
 	if(r<=mid) return query(u<<1,l,r);//在左区间 
 	else if(l>mid) return query(u<<1|1,l,r);//在右区间
	else
	{
		auto left=query(u<<1,l,r);
		auto right=query(u<<1|1,l,r);
		Node res;
		push_up(res,left,right) ;
		return res;
	} 
 }
int main()
{
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	build(1,1,n);
	int op;
	while(m--)
	{
		scanf("%d %d %d",&op,&x,&y);
		if(op==1)
		{
			if(x>y) swap(x,y) ;
			cout<<query(1,x,y).tmax<<endl;
		}
		else
		{
			update(1,x,y);
		}
	}
}

Published 309 original articles · won praise 6 · views 5249

Guess you like

Origin blog.csdn.net/qq_43690454/article/details/104085376
Recommended