最近开始线段树一段时间了,也发现了不少大牛的博客比如HH大牛  ,小媛姐。这个题目是我在看HH大牛的线段树专题是给出的习题,(可以去他博客找找,真心推荐)原本例题是POJ3667
Hotel
 这个题目,是一个求连续空区间的情况,而hdoj这个题目是求给定区间单调连续的最大区间长度,两个题目思路很相似,将节点rt用sum[rt],lsum[rt],rsum[rt]来描述,分别表示rt对应区间即[l,r]内满足条件的区间的最大长度,从左边端点l开始满足条件的最大区间长度,从右边r开始向左的满足条件的最大区间长度。

void PushUp(int rt,int m,int mid)//mid表示更新区间的中点,m表示长度

{

    lsum[rt]=lsum[rt<<1];

    rsum[rt]=rsum[rt<<1|1];

    int t=1;

    if(A[mid]<A[mid+1])

    {

        if(lsum[rt]==(m-(m>>1)))

            lsum[rt]+=lsum[rt<<1|1];

        if(rsum[rt]==(m>>1))

            rsum[rt]+=rsum[rt<<1];

        t= rsum[rt<<1]+lsum[rt<<1|1];

    }

       sum[rt]=max(t,max(sum[rt<<1],sum[rt<<1|1]));

}

PushUp函数和query函数是关键  ,PushUp函数向上更新时,先将lsum[rt]用

lsum[rt<<1]也就是左子区间左边开始的最大长度,如果这个区间长度刚好是l到mid之间的长度,说明区间已经穿过中点了,应该在加上右子区间lsum[rt<<1|1]这部分,类似的可以更新rsum[rt]。对于sum[rt]应该对应rsum[rt<<1]+lsum[rt<<1|1],sum[rt<<1],sum[rt<<1|1]三种情况中的最大值,因为满足条件的最长单调区间可以是左半部分,右半部分,或者贯穿中点。

理解了这部分那么query函数可以按照类似的思路来写,但要注意的是对于贯穿中点的判断条件是A[mid]<A[mid+1],这样才能将两部分加起来。

期间又一次犯二TLE了,原本是用C写的,max函数是用的宏定义,结果里面含有query函数,这样最终可能会两次调用query函数,不超时才怪,好在以前犯过一次,被基友发现了,改成algorithm里面的max就过了。哎,有个能debug基友就是好啊。hhha~

#include<cstdio>

#include<cstring>
#include<algorithm>
#define N 100010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 using namespace std;
int sum[N<<2],rsum[N<<2],lsum[N<<2],A[N]; void PushUp(int rt,int m,int mid)
{
lsum[rt]=lsum[rt<<1];
rsum[rt]=rsum[rt<<1|1];
int t=1;
if(A[mid]<A[mid+1])
{
if(lsum[rt]==(m-(m>>1)))
lsum[rt]+=lsum[rt<<1|1];
if(rsum[rt]==(m>>1))
rsum[rt]+=rsum[rt<<1];
t= rsum[rt<<1]+lsum[rt<<1|1];
}
sum[rt]=max(t,max(sum[rt<<1],sum[rt<<1|1]));
} void build(int l,int r,int rt)
{
if(l==r)
{
sum[rt]=lsum[rt]=rsum[rt]=1;
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt,r-l+1,m);
} void update(int p,int l,int r,int rt)
{
if(l==r)
return;
int m=(l+r)>>1;
if(p<=m)
update(p,lson);
else update(p,rson);
PushUp(rt,r-l+1,m);
} int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
return sum[rt];
}
int m=(l+r)>>1;
if(l==r)
return 1;
int ans=0;
if(R<=m)
ans=max(ans,query(L,R,lson));
else if(L>m)
ans=max(ans,query(L,R,rson));
else
{
ans=max(ans,query(L,R,lson));
ans=max(ans,query(L,R,rson));
int ll,rr;
if(m-L+1>=rsum[rt<<1])
ll=rsum[rt<<1];
else ll=m-L+1;
if(R-m>=lsum[rt<<1|1])
rr=lsum[rt<<1|1];
else rr=R-m;
ans=max(ans,ll);
ans=max(ans,rr);
if(A[m+1]>A[m])
ans=max(ans,ll+rr);
}
return ans;
} int main(void)
{
int T;
int n,m,a,b;
char op[3];
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
scanf("%d",A+i);
build(1,n,1);
while(m--)
{
scanf("%s%d%d",op,&a,&b);
if(op[0]=='U')
{
A[a+1]=b;
update(a+1,1,n,1);
}
else
{
int ans=query(a+1,b+1,1,n,1);
printf("%d\n",ans);
}
}
}
return 0;
}

HDU 3308 LCIS 线段树区间更新的更多相关文章

  1. HDU 3308 LCIS (线段树区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...

  2. HDU 3308 LCIS(线段树单点更新区间合并)

    LCIS Given n integers. You have two operations: U A B: replace the Ath number by B. (index counting ...

  3. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  4. LCIS线段树(区间更新)

    首先线段树每一个节点包含:[b,e],lmax,rmax,max;其中lmax表示从左端点开始连续的最长的增序列长度,rmax表示从e端点开始向左连续的最长下降序列长度,max表示当前区间的连续递增的 ...

  5. HDU 3308 LCIS (线段树&#183;单点更新&#183;区间合并)

    题意  给你一个数组  有更新值和查询两种操作  对于每次查询  输出相应区间的最长连续递增子序列的长度 基础的线段树区间合并  线段树维护三个值  相应区间的LCIS长度(lcis)  相应区间以左 ...

  6. LCIS HDU - 3308 (线段树区间合并)

    LCIS HDU - 3308 Given n integers. You have two operations: U A B: replace the Ath number by B. (inde ...

  7. HDU 3308 (线段树区间合并)

    http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作  : 1 修改 单点  a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...

  8. HDU 5861 Road 线段树区间更新单点查询

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Road Time Limit: 12000/6000 MS (Java/Othe ...

  9. hdu 1698(线段树区间更新)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. 2013年10月13日学习:SQL通过命令语句来创建表

    优点:操作简单,不容易出错,易于调试 缺点:需要记住命令.命令多了就容易混淆,是吧!但是熟悉了时间长了就OK了! step 1. 新建数据库,命名为Test 点击图形化界面中的新建查询,此时就可以输入 ...

  2. Jquery基础整理

    1.简单的JQuery (1)  $(document).ready(function(){ $(document).ready(mydays); alert(“加载完毕,请检查!”); functi ...

  3. linux命令行执行db2存储过程

    存储过程代码如下: CREATE PROCEDURE proc_sum2(IN n INT,OUT sum INT,OUT j INT) BEGIN DECLARE i INT; ; ; ; WHIL ...

  4. Codevs 1814 最长链

    1814 最长链 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 现给出一棵N个结点二叉树,问这棵二叉树中最长链的长度为多少, ...

  5. Codevs 1507 酒厂选址

    1507 酒厂选址 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 传送门 题目描述 Description Abstinence(戒酒)岛的居民们酷爱一种无酒精啤酒 ...

  6. 实例:图像载入、显示、混合与输出[OpenCV 笔记8]

    是的是的,忍着尿意努力更新,就是为了更到wuli男神的部分,当然要把男神放在前面镇楼,欢迎下载配图,具体操作见code wuliEddie.jpg logo.png results.jpg LoadS ...

  7. IOS 学习笔记 2015-03-27 我理解的OC-代理模式

    案例1 KCButton.h // // KCButton.h // Protocol&Block&Category // // Created by Kenshin Cui on 1 ...

  8. C# 利用TextBox的Text属性实现换行加字符 "\r\n"

    要让一个TextBox显示多行文本就得把它的Multiline属性设置为true,可是如果你是要把TextBox的Text属性设置多行文本时,换行符由两个字符组成:"\r\n". ...

  9. Java LoggingAPI 使用方法

    因为不想导入Log4j的jar,项目只是测试一些东西,因此选用了JDK 自带的Logging,这对于一些小的项目或者自己测试一些东西是比较好的选择. Log4j中是通过log4j.properties ...

  10. 网站前端优化 -saveForSelf

    九.网站前端优化 – IMG 9.1.可以优化的图片 图片总共可以分为两类,一个是CSS IMAGES,另一个是产品图片. 9.2.CSS IMAGES CSS图片现在采用的方式是图片合并的方式,这样 ...