LCIS(区间合并)
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 |
Sample Output
1 |
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(区间合并)的更多相关文章
- LCIS(线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- HDU 3308 LCIS (经典区间合并)【线段树】
<题目链接> 题目大意: 给你一段序列,对其进行两种操作,一是修改某个序号的点的值:二是查询某个区间的LCIS(最长上升子序列). 解题分析: 线段树区间合并的典型例题,用求某个区间的LC ...
- hdu-3308 LCIS (线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- HDU 3308 LCIS (线段树·单点更新·区间合并)
题意 给你一个数组 有更新值和查询两种操作 对于每次查询 输出相应区间的最长连续递增子序列的长度 基础的线段树区间合并 线段树维护三个值 相应区间的LCIS长度(lcis) 相应区间以左 ...
- 线段树(区间合并) HDOJ 3308 LCIS
题目传送门 题意:线段树操作:1. 单点更新 2. 求区间的LCIS(longest consecutive increasing subsequence) 分析:注意是连续的子序列,就是简单的区间合 ...
- LCIS HDU - 3308 (线段树区间合并)
LCIS HDU - 3308 Given n integers. You have two operations: U A B: replace the Ath number by B. (inde ...
- 线段树的区间合并 B - LCIS
B - LCIS HDU - 3308 这个是一个很简单很明显的线段树的区间合并,不过区间合并的题目都还是有点难写,建议存个板子. #include <cstdio> #include & ...
- [HDOJ3308]LCIS(线段树,区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意:给定n个数,两个操作: U A B:将位置A的数值改成B Q A B:查询[A,B]内最长 ...
- HDU-3308 LCIS(区间合并)
题目大意:给一个整数序列,m次询问,每次询问某个区间中最长连续上升子序列的长度. 题目分析:线段树区间合并.维护以区间左端开头的.以区间右端点结尾的和区间最长的上升连续序列. 代码如下: # incl ...
随机推荐
- EntityFramework 6.x多个上下文迁移实现分布式事务
前言 自从项目上了.NET Core平台用上了EntityFramework Core就再没碰过EntityFramework 6.x版本,目前而言EntityFramework 6.x是用的最多,无 ...
- [LeetCode] 344 Reverse String && 541 Reverse String II
原题地址: 344 Reverse String: https://leetcode.com/problems/reverse-string/description/ 541 Reverse Stri ...
- 12 Nonlinear Transformation
一.二次假设 实际上线性假设的复杂度是受到限制的, 需要高次假设打破这个限制 假设数据不是线性可分的,但是可以被一个圆心在原点的圆分开, 需要我们重新设计基于该圆的PLA等算法吗 不用, 只需要通过非 ...
- 【Java】关于Java8 parallelStream并发安全的思考
背景 Java8的stream接口极大地减少了for循环写法的复杂性,stream提供了map/reduce/collect等一系列聚合接口,还支持并发操作:parallelStream. 在爬虫开发 ...
- 解决外部编辑器修改Eclipse文件延迟刷新【补充】
在之前的文章,使用gulp解决外部编辑器修改Eclipse文件延迟刷新,原理是用gulp把更改过的项目文件直接复制一份到Tomcat的webapp.root下, 现在补充另外一种方法,双击Server ...
- jQuery中的常用内容总结(二)
jQuery中的常用内容总结(二) 转载请注明地址: http://www.cnblogs.com/funnyzpc/p/7571993.html 前言 距离上次博客更新已经有二十来天了(●′ω`●) ...
- SQLserver学习(四)——T-SQL编程之事务、索引和视图
今天来分享下T-SQL高级编程中的事务.索引.视图,可以和之前的SQL server系列文章结合起来. 一.事务 事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作,这些操作作为一个 ...
- ch1-使用路由-静态资源-404页面-ejs模板
1 package.json 项目文件夹根目录创建这个文件 //要依赖的模块 "dependencies": { //dependency 依赖的复数形式 "expres ...
- 【转】python os.popen 超时问题
python 版本 2.5.4 (在高版本python中提倡使用 subprocess.Popen 取代 os.popen) os.popen 会出现过长时间等待导致阻塞问题, 解决方法如下: [py ...
- java web mysql 入门知识讲解
MySQL学习笔记总结 一.SQL概述: SQL:Structured Query Language的缩写(结构化查询语言) SQL工业标准:由ANSI(ISO核心成员) 按照工业标准编写的SQ ...