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;
}


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

相关文章推荐

hdu 3308 线段树区间 LCIS

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

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

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

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

HDU 3308 LCIS 线段树维护区间lcs

题意: 给一个1~n的数组 操作i把下标为x的值更新为y 操作ii查询区间 x~y的lcs 具体分析写在代码里 ///参考讨论版 ACcode:

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

题意:给一个序列,有两种操作,Q:询问x到y的LCIS长度。U:将序号为x的值改为y。 思路:用线段树来维护序列,每次更改值时就更新树,查询是很快的,查询时要注意。 ...

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

#define _CRT_SECURE_NO_WARNINGS #include #include #include #include using namespace std; #define MAX...

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

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

HDU 3308 LCIS 线段树区间合并

LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi...

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 LCIS Time Limit: 6000/2000 MS (Java/Others) ...

hdu 3308 LCIS 线段树 区间合并

好题一个,区间合并问题 大意就是问某个区间内最长连续上升序列的长度 跟POJ 3667 Hotel 差不多,貌似还更简单一些,因为只有单点更新 用到了lmx, rmx, mx,表示从左端点往右的...

线段树 HDU 3308 LCIS

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 代码风格:http://www.notonlysuccess.com/index.php/se...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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