LCIS线段树(区间更新)
首先线段树每一个节点包含:[b,e],lmax,rmax,max;其中lmax表示从左端点开始连续的最长的增序列长度,rmax表示从e端点开始向左连续的最长下降序列长度,max表示当前区间的连续递增的最长序列长度。对单个节点插入时的信息维护如下:
(1) if 左儿子的右端点的值<右儿子的左端点的值
lmax=左儿子区间长度==左儿子的lmax?左儿子区间长度+右儿子的lmax:左儿子的lmax.
rmax=右儿子区间长度==右儿子的rmax?右儿子区间长度+左儿子的rmax:右儿子的rmax.
max=MAX(lmax,rmax,左儿子的rmax+右儿子的lmax);
(2)否则
lmax=左儿子的lmax;
rmax=右儿子的rmax;
max=MAX(左儿子的max,右儿子的max);
查寻操作如下:
if 当前节点区间==查询区间
返回当前节点的max
否则
返回 MAX(左区间,右区间,跨越边界的长度)
//------------------------------------------------------------------
//---线段树区间更新
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 1000000;
struct Tnode{
int b, e;
int lmax;
int rmax;
int max;
int len(){ return e - b + 1; }
};
Tnode tree[4*MAXN];
int p[MAXN];
int n, m;
int max(int a, int b, int c){
return max(max(a, b), c);
}
void Build(int v, int l, int r){
tree[v].b = l, tree[v].e = r;
tree[v].lmax = tree[v].rmax = tree[v].max = 0;
if (l < r){
int mid = (l + r) >> 1;
Build(2 * v + 1, l, mid);
Build(2 * v + 2, mid + 1, r);
}
}
void Insert(int v, int k, int val){
if (tree[v].b == tree[v].e){
//找到叶节点插入
p[k] = val;
tree[v].lmax = tree[v].rmax = tree[v].max = 1;
return;
}
int mid = (tree[v].b + tree[v].e) >> 1;
if (k <= mid)
Insert(2 * v + 1, k, val);
else
Insert(2 * v + 2, k, val);
//接下来更新
if (p[mid] < p[mid + 1]){
if (tree[2 * v + 1].lmax == tree[2 * v + 1].len())
tree[v].lmax = tree[2 * v + 1].len() + tree[2 * v + 2].lmax;
else
tree[v].lmax = tree[2*v+1].lmax; if (tree[2 * v + 2].rmax == tree[2 * v + 2].len())
tree[v].rmax = tree[2 * v + 2].len() + tree[2 * v + 1].rmax;
else
tree[v].rmax = tree[2*v+2].rmax;
tree[v].max = max(tree[2 * v + 1].max, tree[2 * v + 2].max,tree[2 * v + 1].rmax + tree[2 * v + 2].lmax);
}
else{
tree[v].lmax = tree[2*v+1].lmax;
tree[v].rmax = tree[2 * v + 2].rmax;
tree[v].max = max(tree[2 * v + 1].max,tree[2 * v + 2].max);
}
}
int Qurrey(int v,int l, int r){
if (l == tree[v].b&&r == tree[v].e)
return tree[v].max;
int mid = (tree[v].b + tree[v].e) >> 1;
if (r <= mid)
return Qurrey(2 * v + 1, l, r);
else if (l > mid)
return Qurrey(2 * v + 2, l, r);
else{
if (p[mid] < p[mid + 1]){
int left = max(mid + 1 - tree[2 * v + 1].rmax, l);
int right = min(r, mid + tree[2 * v + 2].lmax);
return max(Qurrey(2 * v + 1, l, mid), Qurrey(2 * v + 2, mid + 1, r), right-left+1);
}
else
return max(Qurrey(2 * v + 1, l, mid), Qurrey(2 * v + 2, mid + 1, r));
}
}
int main(){
int i, T,a,b;
char s;
scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &m);
memset(p, 0, sizeof(p));
Build(0, 0, n - 1);
for (i = 0; i < n; i++){
scanf("%d", &p[i]);
Insert(0, i, p[i]);
}
while (m--){
cin >> s;
scanf("%d%d",&a, &b);
if (s == 'U')
Insert(0, a, b);
else
printf("%d\n", Qurrey(0, a, b));
}
}
return 0;
}
LCIS线段树(区间更新)的更多相关文章
- HDU 3308 LCIS 线段树区间更新
最近开始线段树一段时间了,也发现了不少大牛的博客比如HH大牛 ,小媛姐.这个题目是我在看HH大牛的线段树专题是给出的习题,(可以去他博客找找,真心推荐)原本例题是POJ3667 Hotel 这个题目 ...
- HDU 1556 Color the ball(线段树区间更新)
Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...
- hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新
#1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...
- HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...
- HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...
- HDU 1698 线段树 区间更新求和
一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...
- POJ-2528 Mayor's posters (线段树区间更新+离散化)
题目分析:线段树区间更新+离散化 代码如下: # include<iostream> # include<cstdio> # include<queue> # in ...
- ZOJ 1610 Count the Colors (线段树区间更新)
题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头 ...
- POJ 2528 Mayor's posters (线段树区间更新+离散化)
题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...
随机推荐
- 实用JS系列——面向对象中的类和继承
背景: 在最开始学习JavaScript时,我们就知道,它是一种脚本语言,也有面向对象机制.但它的面向对象继承机制是基于原型的,即Prototype.今天,我们就来找一下JS中OO的影子. 创建类 1 ...
- PHP的几种遍历方法
PHP常用的遍历方法有三种,foreach,for,list()/each()和while,这三种方法中效率最高的是使用foreach语句遍历数组 一.使用for语句循环遍历数组 值得大家注意的是使用 ...
- jQuery中Ajax的属性设置
1.全局设置为同步 $.ajaxSetup({ async: false });
- NAT64与DNS64基本原理概述
NAT64与DNS64基本原理概述 1.NAT64与DNS64背景 在IPv6网络的发展过程中,面临最大的问题应该是IPv6与IPv4的不兼容性,因此无法实现二种不兼容网络之间的互访.为了实现 ...
- HDU 4585 Shaolin(Treap找前驱和后继)
Shaolin Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Su ...
- [bzoj] 3343 教主的魔法 || 带修改分块
原题 长度为n的序列,有两种操作: 1.[l,r]区间每个数+w 2.询问[l,r]区间有多少个数>c 记录lazy数组即可. #include<cstdio> #include&l ...
- BZOJ3143 [Hnoi2013]游走 【高斯消元】
题目 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编 ...
- 《R语言实战》读书笔记--第三章 图形初阶(一)
3.1使用图形 可以使用pdf等函数将图形直接保存在文件中.在运用attach和detach函数的使用中经常出现错误,比如命名重复的问题,所以,应该尽量避免使用这两个函数. plot是一般的画图函数, ...
- linux命令Netstat
1.需求 了解Netstat命令 2.简介 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multi ...
- COM RTS/CTS, DTR/DSR
COM: 串行通讯端口cluster communication port它是串行接口,现在的PC 机一般有两个串行口COM 1 和COM 2 .串行口不同于并行口之处在于它的数据和控制信息是一位接一 ...