You have two operations:
U A B: replace the Ath number by B. (index counting from 0)
Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b].
Each case starts with two integers n , m(0<n,m<=10
5).
The next line has n integers(0<=val<=10
5).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=10
5)
OR
Q A B(0<=A<=B< n).
10 10
7 7 3 3 5 9 9 8 1 8
Q 6 6
U 3 4
Q 0 1
Q 0 5
Q 4 7
Q 3 5
Q 0 2
Q 4 6
U 6 10
Q 0 9
1
4
2
3
1
2
5
1. 左儿子最右边的值 < 右儿子最左边的值 lMax = (左儿子的lMax == 左儿子的len) ? 左儿子的len + 右儿子的lMax : 左儿子的lMax;
rMax = (右儿子的rMax == 右儿子的len) ? 右儿子的len + 左儿子的rMax : 右儿子的rMax;
Max = MAX(左儿子的rMax + 右儿子的lMax, 左儿子的Max, 右儿子的Max, lMax, rMax); 2. 左儿子最右边的值 >= 右儿子最左边的值
lMax = 左儿子的lMax;
rMax = 右儿子的rMax;
Max = MAX(左儿子的Max, 右儿子的Max);
注意:在查寻时,当跨越左右子树时则一这要注意这个,当 左节点的最右边的值< 右节点的最左边的值时,那么有可能最长升序在这时最大,并且不能超过这个范围。
#include<stdio.h>
#define N 500010
struct node
{
int Llcis,Rlcis,lcis;//最左连续升序长度,最右连续升序长度,这个范围的最长连续升序长度
}tree[8*N];
int num[N+5];
int max(int a,int b){ return a>b?a:b;}
void chang_tree(int l,int r,int k)//根据第K个节点的左右节点,计算第K个节点的最左,最右和最长 的升序长度
{
int m=(l+r)/2;
node ltree=tree[k*2],rtree=tree[k*2+1];
if(num[m]>=num[m+1])//当左节点的最右边的值不小右节点的最左边的值时
{
tree[k].Llcis=ltree.Llcis;
tree[k].Rlcis=rtree.Rlcis;
tree[k].lcis=max(ltree.lcis,rtree.lcis);
}
else
{
if(m-l+1==ltree.Llcis) tree[k].Llcis=ltree.Llcis+rtree.Llcis;
else tree[k].Llcis=ltree.Llcis;
if(r-m==rtree.Rlcis) tree[k].Rlcis=rtree.Rlcis+ltree.Rlcis;
else tree[k].Rlcis=rtree.Rlcis;
tree[k].lcis=max(ltree.lcis,ltree.Rlcis+rtree.Llcis);
tree[k].lcis=max(tree[k].lcis,rtree.lcis);
tree[k].lcis=max(tree[k].lcis,tree[k].Llcis);
tree[k].lcis=max(tree[k].lcis,tree[k].Rlcis);
}
}
void build(int l,int r,int k)
{
int m=(l+r)/2;
if(l==r){
tree[k].Llcis=1;
tree[k].lcis=1;
tree[k].Rlcis=1;
return ;
}
build(l,m,k*2);
build(m+1,r,k*2+1);
chang_tree(l,r,k);
}
void updata(int l,int r,int k,int Q,int ans)
{
int m=(l+r)/2;
if(l==Q&&Q==r)
{num[Q]=ans; return ;}
if(Q<=m) updata(l,m,k*2,Q,ans);
if(Q>m) updata(m+1,r,k*2+1,Q,ans);
chang_tree(l,r,k);
}
int maxlen;
void find(int l,int r,int k,int L,int R)
{
int m=(l+r)/2;
if(L<=l&&r<=R){
maxlen=max(tree[k].lcis,maxlen);
return ;
}
if(R<=m) find(l,m,k*2,L,R);
else if(L>m) find(m+1,r,k*2+1,L,R);
else{
find(l,m,k*2,L,R);
find(m+1,r,k*2+1,L,R);
//-----当查寻夸越左右子树时,左子树的最右端点的值小于右子树的最左端点的值------
if(num[m]<num[m+1])
if(L<=m-tree[2*k].Rlcis+1&&m+tree[k*2+1].Llcis<=R)//注意这个条件
maxlen=max(tree[k*2].Rlcis+tree[k*2+1].Llcis,maxlen);
else if(L<=m-tree[2*k].Rlcis+1&&m+tree[k*2+1].Llcis>R)//注意这个条件
maxlen=max(tree[k*2].Rlcis+R-m,maxlen);
else if(L>m-tree[2*k].Rlcis+1&&m+tree[k*2+1].Llcis<=R)//注意这个条件
maxlen=max(m-L+1+tree[k*2+1].Llcis,maxlen);
else maxlen=R-L+1;//最长的升序长度
}
}
int main()
{
int t,n,m,QL,QR;
char c[2];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
build(1,n,1);
while(m--)
{
scanf("%s%d%d",c,&QL,&QR);
if(c[0]=='U') updata(1,n,1,QL+1,QR);
if(c[0]=='Q')
{
maxlen=0; find(1,n,1,QL+1,QR+1);
printf("%d\n",maxlen);
}
}
}
}
hdu3308LCIS(线段树,点更新,段查寻,查寻时一定要注意跨越时如何计算)的更多相关文章
-
Codeforces295A - Greg and Array(线段树的成段更新)
题目大意 给定一个序列a[1],a[2]--a[n] 接下来给出m种操作,每种操作是以下形式的: l r d 表示把区间[l,r]内的每一个数都加上一个值d 之后有k个操作,每个操作是以下形式的: x ...
-
LCIS线段树(区间更新)
首先线段树每一个节点包含:[b,e],lmax,rmax,max;其中lmax表示从左端点开始连续的最长的增序列长度,rmax表示从e端点开始向左连续的最长下降序列长度,max表示当前区间的连续递增的 ...
-
ZOJ 1610 Count the Colors (线段树区间更新)
题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头 ...
-
HDU 3577 Fast Arrangement (线段树区间更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3577 题意不好理解,给你数字k表示这里车最多同时坐k个人,然后有q个询问,每个询问是每个人的上车和下车 ...
-
zoj 1610 Count the Colors(线段树延迟更新)
所谓的懒操作模板题. 学好acm,英语很重要.做题的时候看不明白题目的意思,我还拉着队友一块儿帮忙分析题意.最后确定了是线段树延迟更新果题.我就欣欣然上手敲了出来. 然后是漫长的段错误.... 第一次 ...
-
HDU 1166 敌兵布阵(线段树单点更新,板子题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
-
UESTC 1591 An easy problem A【线段树点更新裸题】
An easy problem A Time Limit: 2000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others ...
-
hihoCoder #1078 : 线段树的区间修改(线段树区间更新板子题)
#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...
-
ZOJ 1610 Count the Color(线段树区间更新)
描述Painting some colored segments on a line, some previously painted segments may be covered by some ...
-
HDU 1166 敌兵布阵(线段树单点更新,区间查询)
描述 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况 ...
随机推荐
-
解析Javascript事件冒泡机制
本资源引自: 解析Javascript事件冒泡机制 - 我的程序人生 - 博客频道 - CSDN.NET http://blog.csdn.net/luanlouis/article/details/ ...
-
MS Project 2007 工期、工时、资源、固定单位、固定工期、固定工时
0. 基本概念 工期:指完成每项项目任务所经历的实际时间,及开始日期和结束时期之差.Project中,工期的默认单位是天. 工时:指将任务分配给资源后,每个资源执行任务的工作时间.Project中,工 ...
-
ACE_Get_Opt解析命令行
ACE_Get_Opt是一种解析命令行参数选项的迭代器. 1:构造方法 ACE_Get_Opt需要引用头文件,#include "ace/Get_Opt.h". ACE_Get_O ...
-
重温CSS3
基础不牢,地动山摇!没办法,只能重温"经典"! 1.CSS3边框:border-radius; box-shadow; border-image border-radius:r1, ...
-
创建帧动画1 - xml方式
废话不多说,先看东西 创建帧动画1 - xml方式 帧动画的创建方式主要以下2种: * 用xml创建动画: * 用代码创建动画: 本文内容主要关注 xml文件 创建帧动画的方式 xml文件 ...
-
js简单实现自动轮播
//简单一个布局存放图片 <div class="lb"> <div class="lbt"> <img src="im ...
-
java----javaBean
Beanutils 工具类的下载 http://commons.apache.org/proper/commons-beanutils/ 使用 应用的时候还需要一个logging包http://com ...
-
Math、Random、System、BigInteger、Date、DateFormat、Calendar类,正则表达式_DAY14
1:Math&大数据类四则运算 X abs(X x) double random() 产生随机数 double ceil(double a) 向上取整 double flo ...
-
今天搞log4net插入错误日志去mysql数据库的时候出现了点问题,已解决。记录下解决方案
先上图 配置log4net的时候要填这项,可是这个value我不知道啊.....上图里的value是我用下面的方法获取的 MySqlConnection con = new MySqlConnecti ...
-
【hive】时间段为五分钟的统计
问题内容 今天遇到了一个需求,需求就是时间段为5分钟的统计.有数据的时间戳.对成交单量进行统计. 想法思路 因为数据有时间戳,可以通过from_unixtime()来获取具体的时间. 有了具体的时间, ...