hzoi 山海经(传世经典版)

线段树的题

纯瘤子题555

就是用最长子段和的思路,在每次赋值后记录端点就行

Code

#include<bits/stdc++.h>
using namespace std;
#define lson (rt<<1)
#define rson (rt<<1|1)
const int maxn=1e5+10;
int n,m;
struct node
{
	int l,r;
	long long sum,max_l,max_r,maxx;
	long long l_right,r_left;
	long long ll,rr;
}tree[maxn<<2];
int a[maxn];
void pushup(int rt)
{
	tree[rt].sum = tree[lson].sum+tree[rson].sum;
	if (tree[lson].max_l>=tree[lson].sum+tree[rson].max_l)
	{
		tree[rt].max_l = tree[lson].max_l;
		tree[rt].l_right = tree[lson].l_right;
	}
	else
	{
		tree[rt].max_l = tree[lson].sum+tree[rson].max_l;
		tree[rt].l_right = tree[rson].l_right;
	}
	if (tree[rson].max_r>tree[rson].sum+tree[lson].max_r)
	{
		tree[rt].max_r = tree[rson].max_r;
		tree[rt].r_left = tree[rson].r_left;
	}
	else
	{
		tree[rt].max_r = tree[rson].sum+tree[lson].max_r;
		tree[rt].r_left = tree[lson].r_left;
	}
	if (tree[lson].maxx>=max(tree[rson].maxx,tree[lson].max_r+tree[rson].max_l))
	{
		tree[rt].maxx = tree[lson].maxx;
		tree[rt].ll = tree[lson].ll;
		tree[rt].rr = tree[lson].rr;
	}
	else if (tree[rson].maxx>max(tree[lson].maxx,tree[lson].max_r+tree[rson].max_l))
	{
		tree[rt].maxx = tree[rson].maxx;
		tree[rt].ll = tree[rson].ll;
		tree[rt].rr = tree[rson].rr;
	}
	else
	{
		tree[rt].maxx = tree[lson].max_r+tree[rson].max_l;
		tree[rt].ll = tree[lson].r_left;
		tree[rt].rr = tree[rson].l_right;
	}
}
void build(int rt,int l,int r)
{
	tree[rt].l = l;
	tree[rt].r = r;
	if (l == r)
	{
		tree[rt].sum = a[l];
		tree[rt].max_l = a[l];
		tree[rt].max_r = a[l];
		tree[rt].maxx = a[l];
		tree[rt].ll=l;
		tree[rt].rr=l;
		tree[rt].l_right=l;
		tree[rt].r_left=l;
		return;
	}
	int mid = (l+r) >> 1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	pushup(rt);
}
node query(int rt,int l,int r)
{
	if (tree[rt].l == l && tree[rt].r == r)
	{
		return tree[rt];
	}
	int mid = (tree[rt].l+tree[rt].r) >> 1;
	if (r<=mid) return query(lson,l,r);
	else if (l>mid) return query(rson,l,r);
	else
	{
		node left = query(lson,l,mid);
		node right = query(rson,mid+1,r);
		node res;
		res.sum = left.sum+right.sum;
		if (left.max_l>=left.sum+right.max_l)
		{
			res.max_l = left.max_l;
			res.l_right = left.l_right;
		}
		else
		{
			res.max_l = left.sum+right.max_l;
			res.l_right = right.l_right;
		}
		if (right.max_r>right.sum+left.max_r)
		{
			res.max_r = right.max_r;
			res.r_left = right.r_left;
		}
		else
		{
			res.max_r = right.sum+left.max_r;
			res.r_left = left.r_left;
		}
		if (left.maxx>=max(right.maxx,left.max_r+right.max_l))
		{
			res.maxx = left.maxx;
			res.ll = left.ll;
			res.rr = left.rr;
		}
		else if (right.maxx>max(left.maxx,left.max_r+right.max_l))
		{
			res.maxx = right.maxx;
			res.ll = right.ll;
			res.rr = right.rr;
		}
		else
		{
			res.maxx = left.max_r+right.max_l;
			res.ll = left.r_left;
			res.rr = right.l_right;
		}
		return res;
	}
}
int main()
{
	cin >> n >> m;
	for (int i=1;i<=n;i++) cin >> a[i];
	build(1,1,n);
	for (int i=1;i<=m;i++)
	{
		int x,y;
		cin >> x >> y;
		node ans=query(1,x,y);
		cout << ans.ll << " " << ans.rr << " " << ans.maxx << endl;
	}
	return 0;
}
posted @ 2026-03-24 12:11  msjing  阅读(1)  评论(0)    收藏  举报