最大連続セグメントおよびサブセグメントツリー思考-----範囲

長さN Aの列の数、及びMの指示が与えられると、各命令は、以下のいずれかであってもよいです。

1、 "1つのXY"、クエリ間隔[X、Y]は最大連続サブセグメント、すなわちmaxx≤l≤r≤y{Σri= LA [I]}です。

Yに2、 "2 XY"、A [X]。

各queryコマンドについては、出力整数の答え。

入力フォーマット
最初の行の二つの整数N、M。

Nの第2行は、A [i]とする整数です。

次は、3 M線が各整数K、X、Y、K = 1がk = 2が変形を表し、クエリ(この場合には、x> yの場合、X、Yを入れ替える)ことを示しています。

出力フォーマット
出力は、各クエリコマンドの整数の答えを表します。

行ごとの各回答。

データ範囲
N≤500000、M≤100000
入力サンプル:
。5. 3
。1. 4 5 2 -3
。1 3 2
2 2-1
。1 3 2
出力サンプル:
2
-1

分析:
我々は、4つの情報を維持する必要がある
。1.最大プレフィックスと
2最大サフィックスと
前記最大連続サブセクション及び
4つのセクションと
よく維持4を操作します。
3私たちは、
単純な左セクションの最大のサブセグメントがあるので、ちょうど左のインターバル間隔を求め、場合
間隔がちょうどいい範囲で非常に簡単にあなたを求める場合は、右欄の最大範囲であると
、サブ区間の間隔について尋ねられた場合、それが残っています接尾辞や接頭辞+右との最大範囲の最大範囲
最大撮影する3。
1と2 TELLを強調
間隔がちょうど左側のセクションでは非常にシンプルな接頭辞を求めるなら、左の最大のセクションで、
クエリ間隔ちょうど右の間隔は、単に右の範囲であれば最大値と接尾辞。
左側のセクションのクエリ間隔カバレッジ場合は、右の範囲もあり、インターバル左と+右の間隔をし、その最大の接頭間隔で
問合せ部は、右の範囲をカバーし、左側のセクションもある場合は、そのゾーンの右部分で、+左のプレフィックスの最大範囲と
4つのテイク最大



#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);
		}
	}
}

公開された309元の記事 ウォンの賞賛6 ビュー5249

おすすめ

転載: blog.csdn.net/qq_43690454/article/details/104085376
おすすめ