正放的瓶塞

导航

线段树技巧练习--GSS1

GSS系列

1: 给定序列(正负)求区间最大值

题面:
给n,n个数
给m,m个询问 x,y
输出(x,y)区间中的区间最大值

线段树增加内容:lmax,rmax :左右最大
dat :表示该段最大值

部分代码

udpate部分

inline void update(int x) {
	c[x].sum=c[lson(x)].sum+c[rson(x)].sum;
	c[x].lmax=max(c[lson(x)].lmax,c[lson(x)].sum+c[rson(x)].lmax);
	c[x].rmax=max(c[rson(x)].rmax,c[rson(x)].sum+c[lson(x)].rmax);
	c[x].dat=max(max(c[lson(x)].dat,c[rson(x)].dat),c[lson(x)].rmax+c[rson(x)].lmax);
}

avatar

蓝色为lmax,绿色为rmax
结合图例和代码 想一想,为什么?

build部分

void build(int x,int l,int r) {
	if (l==r) {
		c[x].dat=c[x].sum=c[x].lmax=c[x].rmax=read();
		return;
	}
	int mid=(l+r)>>1;
	build(lson(x),l,mid);
	build(rson(x),mid+1,r);
	update(x);
	
}

较为有趣的是输入方式。

query部分

inline note query(int x,int l,int r,int ql,int qr) {
	if (ql<=l&&qr>=r) return c[x];
	int mid=(l+r)>>1;
	if (ql>mid) return query(rson(x),mid+1,r,ql,qr);
	if (qr<=mid) return query(lson(x),l,mid,ql,qr);
	else {
		note ans,a,b;
		a=query(lson(x),l,mid,ql,qr);
		b=query(rson(x),mid+1,r,ql,qr);
		ans.sum=a.sum+b.sum;
		ans.dat=max(a.dat,a.rmax+b.lmax);
		ans.dat=max(ans.dat,b.dat);
		ans.lmax=max(a.lmax,a.sum+b.lmax);
		ans.rmax=max(b.rmax,b.sum+a.rmax);
		return ans;
		
	}
}

此处返回值是一个note(线段树)型
思想类似于普通线段树 懂得都懂:D

可以了...
贴一下源代码

#include<iostream>
#include<algorithm>
#include<cstdio>

#define M 500050 

using namespace std;

inline int read() {
	int f=1,x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if (ch=='-') f=-1;
		ch=getchar();
	}
	while(ch<='9'&&ch>='0') 
		x=x*10+ch-'0',ch=getchar();
	return f*x;
}

int n,m;

struct note {
	int sum,lmax,rmax,dat;	
}c[M<<2];

inline int lson(int x) {return x<<1;}
inline int rson(int x) {return x<<1|1;}

inline void update(int x) {
	c[x].sum=c[lson(x)].sum+c[rson(x)].sum;
	c[x].lmax=max(c[lson(x)].lmax,c[lson(x)].sum+c[rson(x)].lmax);
	c[x].rmax=max(c[rson(x)].rmax,c[rson(x)].sum+c[lson(x)].rmax);
	c[x].dat=max(max(c[lson(x)].dat,c[rson(x)].dat),c[lson(x)].rmax+c[rson(x)].lmax);
}

void build(int x,int l,int r) {
	if (l==r) {
		c[x].dat=c[x].sum=c[x].lmax=c[x].rmax=read();
		return;
	}
	int mid=(l+r)>>1;
	build(lson(x),l,mid);
	build(rson(x),mid+1,r);
	update(x);
	
}

inline note query(int x,int l,int r,int ql,int qr) {
	if (ql<=l&&qr>=r) return c[x];
	int mid=(l+r)>>1;
	if (ql>mid) return query(rson(x),mid+1,r,ql,qr);
	if (qr<=mid) return query(lson(x),l,mid,ql,qr);
	else {
		note ans,a,b;
		a=query(lson(x),l,mid,ql,qr);
		b=query(rson(x),mid+1,r,ql,qr);
		ans.sum=a.sum+b.sum;
		ans.dat=max(a.dat,a.rmax+b.lmax);
		ans.dat=max(ans.dat,b.dat);
		ans.lmax=max(a.lmax,a.sum+b.lmax);
		ans.rmax=max(b.rmax,b.sum+a.rmax);
		return ans;
		
	}
}

int main() {
	n=read();
	build(1,1,n);
	m=read();
	int x,y;
	for (int i=1;i<=m;i++) {
		x=read();y=read();
		printf("%d\n",query(1,1,n,x,y).dat);
	}
	return 0;

}

溜了三( ᐛ )

posted on 2020-11-18 21:32  正放的瓶塞  阅读(88)  评论(0编辑  收藏  举报