HDU 3308 LCIS 线段树维护区间lcs

原创 2016年05月31日 21:45:02

题意:

给一个1~n的数组

操作i把下标为x的值更新为y

操作ii查询区间 x~y的lcs

具体分析写在代码里

///参考讨论版

ACcode:

#include <cstdio>
#include <algorithm>
#define tmp (st<<1)
#define mid ((l+r)>>1)
#define lson l,mid,tmp
#define rson mid+1,r,tmp|1
#define len (r-l+1)
#define maxn 100002
using namespace std;
int my[maxn],sum[maxn<<2],lsum[maxn<<2],rsum[maxn<<2];
inline void push_up(int st,int l,int r){
    lsum[st]=lsum[tmp];
    rsum[st]=rsum[tmp|1];
    sum[st]=max(sum[tmp],sum[tmp|1]);
    if(my[mid]<my[mid+1]){///如果第mid+1大于mid 那么对于左子树的右lcs和右子树的左lcs可以合并
        if(lsum[st]==len-(len>>1))lsum[st]+=lsum[tmp|1];
        if(rsum[st]==len>>1)rsum[st]+=rsum[tmp]; 
        
        sum[st]=max(sum[st],lsum[tmp|1]+rsum[tmp]);
    }
}
inline void build(int l,int r,int st){
    if(l==r){
        sum[st]=lsum[st]=rsum[st]=1;
        return ;
    }
    build(lson);
    build(rson);
    push_up(st,l,r);
}
inline void updata(int t,int l,int r,int st){
    if(l==r)return ;
    if(t<=mid)updata(t,lson);
    if(t>mid)updata(t,rson);
    push_up(st,l,r);
}
inline int query(int L,int R,int l,int r,int st){
    if(L<=l&&r<=R)return sum[st];
    if(R<=mid)return query(L,R,lson);
    if(L>mid)return query(L,R,rson);
    int ans,lans,rans;
    lans=query(L,R,lson);
    rans=query(L,R,rson);
    ans=max(lans,rans);
    if(my[mid]<my[mid+1]){///同上
        int temp=min(rsum[tmp],mid-L+1)+min(lsum[tmp|1],R-mid);
        ans=max(ans,temp);
    }
    return ans;
}
int main(){
    int loop,n,q,x,y;
    char str[4];
    scanf("%d",&loop);
    while(loop--){
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;++i)scanf("%d",&my[i]);
        build(1,n,1);
        while(q--){
            scanf("%s%d%d",str,&x,&y);
            if(str[0]=='Q')
                printf("%d\n",query(++x,++y,1,n,1));
            else{
                my[++x]=y;
                updata(x,1,n,1);
            }
        }
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

HDU3308-LCIS-线段树区间合并

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目大意:给n个数,两种操作                   1:U  a,b   更新...
  • wlxsq
  • wlxsq
  • 2015年08月10日 13:39
  • 467

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

题意  给你一个数组  有更新值和查询两种操作  对于每次查询  输出对应区间的最长连续递增子序列的长度 基础的线段树区间合并  线段树维护三个值  对应区间的LCIS长度(lcis)  对应区间以...
  • acvay
  • acvay
  • 2015年08月11日 09:01
  • 812

hdu 3308 线段树区间 LCIS

题意:        求一个序列相应期间的最长上升子串。期间会有修改和询问。 解:       线段树当前区间最长前缀,后缀,最长子区间,开始数字,结束数字。 单点更新,区间操作。 做题过程:...

HDU3308:LCIS(线段树区间合并)

Problem Description Given n integers. You have two operations: U A B: replace the Ath number by B...

hdu 3308 LCIS 最大连续递增字串长 线段树区间合并

这是我做的第二个线段树区间合并的问题,之前那个hotel还是借助大神的报告来写的,这个总算是独立自主的完成 这个问题是单点更新,所以不用写push_down,延迟标记…… 一个状态记录的是 st...

hdu3308 LCIS(线段树区间合并)

题目链接:hdu3308/*hdu3308 LCIS 线段树区间合并 题目大意: 求一段区间内的连续最长 思路: 记录以区间左端点开始的LCIS,以区间右端点结尾的LCIS以及整个区间...

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

题意: 有两种操作 Q a b 是询问区间[a,b][a,b]内最大的LCIS(最长连续上升子序列) U a b是更新节点a的值为b 解析: 这题和 UESTC 360 Anoth...

hdu.3308 LCIS(线段树,区间合并+单点更新)

区间合并做得

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

题目传送:LCIS 线段树,区间合并,一次过啦,没有纠结,这几天过的最愉快的一个题 思路:求最长连续上升子序列,外带单点更新,经典的线段树题目。具体看代码注释 AC代码: ...

hdu 3308 LCIS 线段树 区间合并

好题一个,区间合并问题 大意就是问某个区间内最长连续上升序列的长度 跟POJ 3667 Hotel 差不多,貌似还更简单一些,因为只有单点更新 用到了lmx, rmx, mx,表示从左端点往右的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 3308 LCIS 线段树维护区间lcs
举报原因:
原因补充:

(最多只允许输入30个字)