首先线段树每一个节点包含:[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线段树(区间更新)的更多相关文章

  1. HDU 3308 LCIS 线段树区间更新

    最近开始线段树一段时间了,也发现了不少大牛的博客比如HH大牛  ,小媛姐.这个题目是我在看HH大牛的线段树专题是给出的习题,(可以去他博客找找,真心推荐)原本例题是POJ3667 Hotel 这个题目 ...

  2. HDU 1556 Color the ball(线段树区间更新)

    Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...

  3. hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新

    #1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...

  4. HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...

  5. HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...

  6. HDU 1698 线段树 区间更新求和

    一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...

  7. POJ-2528 Mayor's posters (线段树区间更新+离散化)

    题目分析:线段树区间更新+离散化 代码如下: # include<iostream> # include<cstdio> # include<queue> # in ...

  8. ZOJ 1610 Count the Colors (线段树区间更新)

    题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头 ...

  9. POJ 2528 Mayor's posters (线段树区间更新+离散化)

    题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...

随机推荐

  1. android配置开发环境

    1.下载Java SE并安装. 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 配置环境变量 我的电脑- ...

  2. 什么是SQL注入?(理解)

    SQL注入攻击是黑客对数据库进行攻击的常用手段之一.一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,注入者可以在表单中输入一段数据库查询代码并提交,程序将提交的信息拼凑生成一个完整s ...

  3. spring in action 学习笔记四:bean的生命周期

    bean 的生命周期分为:一个是ApplicationContext的容器的bean的生命周期,另一个是BeanFactory容器的生命周期. 首先介绍一下:ApplicationContext的容器 ...

  4. Linux下mknod详解

    mknod - make block or character special filesmknod [OPTION]... NAME TYPE [MAJOR MINOR] option 有用的就是 ...

  5. Topcoder SRM 603 div1题解

    昨天刚打了一场codeforces...困死了...不过赶在睡前终于做完了- 话说这好像是我第一次做250-500-1000的标配耶--- Easy(250pts): 题目大意:有一棵树,一共n个节点 ...

  6. Jquery CheckBox 选中和非选中

    if($("input[name='is_pay']").prop('checked')) { $("input[name='is_pay']").prop(' ...

  7. HDU 3389 Game (阶梯博弈)

    Game Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status D ...

  8. BS4爬取豆瓣电影

    爬取豆瓣top250部电影 ####创建表: #connect.py from sqlalchemy import create_engine # HOSTNAME='localhost' # POR ...

  9. 使用 WideCharToMultiByte Unicode 与 UTF-8互转

    1.简述 最近在发送网络请求时遇到了中文字符乱码的问题,在代码中调试字符正常,用抓包工具抓的包中文字符显示正常,就是发送到服务器就显示乱码了,那就要将客户端和服务器设置统一的编码(UTF-8),而我们 ...

  10. 链表各种操作及其实现方法(c实现)

    链表是一种最简单的数据结构之一,经常会被面试官用来考察应聘者的基础扎不扎实,最近也到了求职季,所以我把自己对链表的一些理解写出来,希望能跟大家交流交流: 链表的概念其实挺简单,无非就是一个利用指针将数 ...