LCIS

Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 12 Accepted Submission(s): 11
 
Problem Description
Given n integers.
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].
 
Input
T in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=105).
The next line has n integers(0<=val<=105).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=105)
OR
Q A B(0<=A<=B< n).
 
Output
For each Q, output the answer.
 
Sample Input
1
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
 
Sample Output
1
1
4
2
3
1
2
5
 
Author
notonlysuccess
 
Source
HDOJ Monthly Contest – 2010.02.06
 
Recommend
wxl
 
/*
题意:给你一个长度为n的序列,两种操作:U A B 将第A个数换成B,Q A B 询问区间[A B] 内的最长上升连续子序列的长度 初步思路:首先线段树要维护:此节点的区间 是不是靠左的,是不是靠右的,节点最长的上升子序列的长度,区间左边的值,右
边的值 #补充:区间合并的时候考虑的方面不全面,如果左儿子是完全的上升连续子序列,右儿子的上升连续子序列左右端点都不占,那
么这个时候,按照上面的思路,左右儿子就不能合并,这样的话,就会少了一种情况,节点需要维护的值加上,一个区间的
左端点,右端点,区间连续的长度。 #补充:区间合并已经没问题了,现在的问题就是查询的时候有bug,不能只考虑左右儿子,这样会漏掉很多种情况
*/
#include<bits/stdc++.h>
using namespace std;
/****************************线段树基础模板*********************************/
const int maxn=+; #define lson i*2, l, m
#define rson i*2+1, m+1, r
struct node{
int l,r,c;//区间左右端点,区间的长度
int val_l,val_r;//表示左边的值,表示右边的值
int res_l,res_m,res_r;//表示左端点,中间,右端点的最长连续上升子序列的长度
};
struct Segtree{ node sum[maxn<<]; void PushUp(int i)//向上更新节点 //× √
{
//分别比较左右儿子 //这个是不需要讨论的
sum[i].val_l=sum[i*].val_l;
sum[i].val_r=sum[i*+].val_r;
sum[i].res_l=sum[i*].res_l;//左边界的连续上升子序列的长度肯定是左儿子的
sum[i].res_r=sum[i*+].res_r;//右边界的连续上升子序列的长度肯定是右儿子的 sum[i].res_m=max(sum[i*].res_m,sum[i*+].res_m);//区间的连续上升子序列的长度肯定是的左右的最大值 if(sum[i*].val_r<sum[i*+].val_l){//左右区间可以对接,也就是可以合并的 if(sum[i*].res_l==sum[i*].c){//如果左儿子的区间是完全的上升连续序列 sum[i].res_l+=sum[i*+].res_l;//那么i节点的左边界的连续上升序列的长度还要加上右儿子的左边界的连续上升序列的长度
}
if(sum[i*+].res_r==sum[i*+].c){//如果右儿子的区间是完全的上升连续序列
sum[i].res_r+=sum[i*].res_r;
}
sum[i].res_m=max(sum[i].res_m,(sum[i*].res_r+sum[i*+].res_l) );//那么i节点的最长上升连续序列还要和左右区间接起来的比较一下
}
} void build(int i,int l,int r)
{
sum[i].l=l;
sum[i].r=r;
sum[i].c=r-l+;
if(l==r)//输入根节点的值并且初始化数据
{
scanf("%d",&sum[i].val_l);
sum[i].val_r=sum[i].val_l;
// cout<<"i= "<<i<<" "<<sum[i].val_l<<" "<<sum[i].val_r<<endl;
sum[i].res_r=sum[i].res_l=sum[i].res_m=;//从左开始的上升组序列的长度,右边的,中间的
return ;
} int m=(l+r)>>;
build(lson);
build(rson);
PushUp(i);
}
int query(int ql,int qr,int i,int l,int r)
{
if(ql<=l && r<=qr){
// cout<<"("<<l<<","<<r<<")"<<" sum[i].res_m="<<sum[i].res_m<<endl;
return sum[i].res_m;
} int m=(l+r)>>;
int res=;
if(ql<=m) res = max( res,query(ql,qr,lson) ); if(m<qr) res =max( res,query(ql,qr,rson) ); if(sum[*i].val_r < sum[*i+].val_l){//如果左右区间能接起来的话
// cout<<"i="<<i<<endl;
// cout<<"min(m-l+1,sum[2*i].res_r)="<<min(m-l+1,sum[2*i].res_r)<<" min(r-m,sum[2*i+1].res_l))="<<min(r-m,sum[2*i+1].res_l)<<endl;
// cout<<"m-l+1="<<m-l+1<<endl;
// cout<<"sum[2*i].res_r="<<sum[2*i].res_r<<endl;
// cout<<"r-m="<<r-m<<endl;
// cout<<"sum[2*i+1].res_l="<<sum[2*i+1].res_l<<endl;
res = max(res , min(m-ql+,sum[*i].res_r)+min(qr-m,sum[*i+].res_l));
}
return res;
} void update(int id,int val,int i,int l,int r)
{
if(l==r)//更新到根节点了
{
sum[i].val_l=sum[i].val_r=val;
return ;
}
int m=(l+r)>>;
if(id<=m) update(id,val,lson);
else update(id,val,rson); PushUp(i);//用来向上回溯
}
}segtree;
/****************************线段树基础模板*********************************/
int t;
int n,m;
char op[];
int a,b;
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
//输入
segtree.build(,,n); // for(int i=1;i<=25;i++){
// cout<<"*************************"<<endl;
// cout<<"i= "<<i<<endl;
// cout<<"l,r,c "<<segtree.sum[i].l<<" "<<segtree.sum[i].r<<" "<<segtree.sum[i].c<<endl;
// cout<<"val "<<segtree.sum[i].val_l<<" "<<segtree.sum[i].val_r<<endl;
// cout<<"res "<<segtree.sum[i].res_l<<" "<<segtree.sum[i].res_r<<" "<<segtree.sum[i].res_m<<endl;
// } for(int i=;i<m;i++){
scanf("%s",op);
// cout<<op<<" ";
if(op[]=='U'){//替换
scanf("%d%d",&a,&b);
// cout<<a<<" "<<b<<endl;
a++;
segtree.update(a,b,,,n); // cout<<"update a= "<<a<<" b="<<b<<endl;
// cout<<"l,r,c "<<segtree.sum[1].l<<" "<<segtree.sum[1].r<<" "<<segtree.sum[1].c<<endl;
// cout<<"val "<<segtree.sum[1].val_l<<" "<<segtree.sum[1].val_r<<endl;
// cout<<"res "<<segtree.sum[1].res_l<<" "<<segtree.sum[1].res_r<<" "<<segtree.sum[1].res_m<<endl;
// for(int i=1;i<=25;i++){
// cout<<"*************************"<<endl;
// cout<<"i= "<<i<<endl;
// cout<<"l,r,c "<<segtree.sum[i].l<<" "<<segtree.sum[i].r<<" "<<segtree.sum[i].c<<endl;
// cout<<"val "<<segtree.sum[i].val_l<<" "<<segtree.sum[i].val_r<<endl;
// cout<<"res "<<segtree.sum[i].res_l<<" "<<segtree.sum[i].res_r<<" "<<segtree.sum[i].res_m<<endl;
// }
}else{
scanf("%d%d",&a,&b);
// cout<<a<<" "<<b<<endl;
a++;
b++;
// cout<<"a="<<a<<" b="<<b<<endl;
printf("%d\n",segtree.query(a,b,,,n));
}
}
}
return ;
}

LCIS(区间合并)的更多相关文章

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

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

  2. HDU 3308 LCIS (经典区间合并)【线段树】

    <题目链接> 题目大意: 给你一段序列,对其进行两种操作,一是修改某个序号的点的值:二是查询某个区间的LCIS(最长上升子序列). 解题分析: 线段树区间合并的典型例题,用求某个区间的LC ...

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

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

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

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

  5. 线段树(区间合并) HDOJ 3308 LCIS

    题目传送门 题意:线段树操作:1. 单点更新 2. 求区间的LCIS(longest consecutive increasing subsequence) 分析:注意是连续的子序列,就是简单的区间合 ...

  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. 线段树的区间合并 B - LCIS

    B - LCIS HDU - 3308 这个是一个很简单很明显的线段树的区间合并,不过区间合并的题目都还是有点难写,建议存个板子. #include <cstdio> #include & ...

  8. [HDOJ3308]LCIS(线段树,区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意:给定n个数,两个操作: U A B:将位置A的数值改成B Q A B:查询[A,B]内最长 ...

  9. HDU-3308 LCIS(区间合并)

    题目大意:给一个整数序列,m次询问,每次询问某个区间中最长连续上升子序列的长度. 题目分析:线段树区间合并.维护以区间左端开头的.以区间右端点结尾的和区间最长的上升连续序列. 代码如下: # incl ...

随机推荐

  1. vue源码学习-vnode的挂载和更新流程

    概述 本文主要介绍在视图的渲染过程中,Vue 是如何把 vnode 解析并挂载到页面中的.我们通过一个最简单的例子来分析主要流程: <div id="app"> {{s ...

  2. js的严格模式详解

    什么是js的严格模式? 严格模式指的是使js在更为严格的条件下运行.严格模式的主要作用是规范我们写代码习惯,以及为js升级做好铺垫.  如何使用严格模式? <script> //直接在代码 ...

  3. MongoDB的全文检索(Text Search)功能

    自己的项目中用到了mongodb,需要做一个搜索功能,刚开始不知道怎么搞,查了mongodb有个全文检索功能. 全文检索分为两步 第一,建立索引 db.stores.createIndex( { na ...

  4. mysql error 1130 hy000:Host 'localhost' is not allowed to connect to this mysql server 解决方案

    ERROR 1130 (HY000): Host 'localhost' is not allowed to connect to this MySQL server D:\Wamp\mysql-\b ...

  5. 最近做的floyd的题目

    基础:    HDU1596    HDU2112     HDU1874     HDU1869     HDU2066     HDU2094    HDU2544  稍加复杂: HDU1217 ...

  6. IDL 字符串

    1.创建字符串 字符串和字符串数组通过赋值或函数方式来创建.在IDL字符串用" "或' '括起来表示. IDL> s1="abcdef" IDL> ...

  7. c#接口和抽象类比较

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  8. OpenSCAD 建模:矿泉水瓶花洒

    下载地址:https://github.com/ZhangGaoxing/openscad-models/tree/master/Sprinkle 代码: module screw(r=){ ::]) ...

  9. win10 uwp json

    本文讲的是关于在uwp使用json的简单使用,json应用很多,因为我只是写简单使用,说的东西可能不对或者不符合每个人的预期.如果觉得我有讲的不对的,就多多包含,或者直接关掉这篇文章,但是请勿生气或者 ...

  10. Maven 开发hibernate存在的诸多问题

    项目结构: 开发平台: maven version 3.5 eclipse 4. 7 oxyen 最新:hibernate 5.x 引入问题 官网提供的必需选择只有 这个 当然还需要我们单独配置mys ...