本文主要介绍用线段树来维护(最大区间和,最大子段和,最长连续上升子序列)的问题。
HDU 1540 Tunnel Warfare(最长连续区间+单点修改)
洛谷 P2894 [USACO08FEB]酒店Hotel(最长连续区间+区间修改)
吉首大学2019年程序设计竞赛-白山茶与红玫瑰(最长连续区间+区间修改)
SPOJ - GSS1 Can you answer these queries I(最大子段和)
HDU3308 LCIS(区间最长连续上升子序列)
HDU 1540 Tunnel Warfare(最长连续区间+单点修改)
题意:有三种操作:
操作一:某个村庄被毁灭。
操作二:给出一个村庄的坐标,求包含包含这个村庄的的最长未被村庄的长度。
操作三:最后一个被摧毁的村庄被修复。
题解:首先我们可以想到用线段树来维护最长连续区间长度,我们现在可以用1代表改点没有被破坏,用0表示改点被破坏,然后用一个栈或数组来装上次破坏的点。然后就是线段树维护1的最长长度了,详解请看代码。
#include
#include
#include
#include
#include
洛谷 P2894 [USACO08FEB]酒店Hotel(最长连续区间+区间修改)
题意:有n代表有n个房间,编号为1-n,开始都为空房,有m行操作,以下 每行先输入一个数 i ,表示一种操作:
若i为1,表示查询房间,再输入一个数x,表示在1-n 房间中找到长度为x的连续空房,输出连续x个房间中左端的房间号,尽量让这个房间号最小,若找不到长度为x的连续空房,输出0。
若i为2,表示退房,再输入两个数 x,y 代表 让房间号 x-x+y-1 的房间为空。
题解:这是一个最长连续区间,区间修改的裸题,只是注意找连续区间最左端的房间号(可以好好理解下下面代码的Find_pos函数)。
#include
#include
#include
#include
#include
吉首大学2019年程序设计竞赛-白山茶与红玫瑰(最长连续区间+区间修改)
题意:现在给出一段序列,只有0和1,现在有两种操作:
操作一:给出[l,r],求出该区间内最长连续0区间的长度。
操作二:给出[l,r],将该区间的0全部变成1,1全部变成0。
题解:现在建立两棵线段树,一个保存最长连续1区间长度,一个保存最长连续0区间长度,在执行操作一:就是常规求法就行了,在进行操作二时,将对应区间的对应数组的值全部交换,这样两者刚好反过来,就是我们要求的值。
注意:因为翻转两次就等于没有翻转,所以lazy数组,初值为0,1表示要翻转,然后每次修改都将对应lazy数组值异或1就行了。
#include
#include
#include
#include
#include
SPOJ - GSS1 Can you answer these queries I(最大子段和)
题意:给出一段序列,给出m次询问,让你给出该区间内最大连续子段和。
题解:跟最长连续子序列差不多,这是一道模板题,直接上代码。
#pragma comment(linker, "/STACK:102400000,102400000")
#include
#include
#include
#include
#include
HDU3308 LCIS(区间最长连续上升子序列)
题意:求区间最长连续上升子序列。
PS:因为要更改节点的值,所以不能用dp做。这里就可以用线段树来维护。
这就是一个裸的线段树求最长上升子序列的题,细节看代码,主要是要注意更新左子树,右子树,和区间最长子序列长度。
#pragma comment(linker, "/STACK:102400000,102400000")
#include
#include
#include
#include
#include