LCIS

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6069    Accepted Submission(s): 2635

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
 
题意:求解区间 a - b之内的最大连续上升子序列
题解:线段树区间合并 ,主要是PushUp操作 和 查询操作 ,在线段树中最长子序列可能在左子树也可能在右子树 ,也可能从左子树到右子树
,所以我们在在树的结构体中增加三个变量(左边的最长区间,右边的最长区间,最长合区间).然后其余的详细解释都在代码中了,有兴趣的朋友可以
看看.主要是理解左子树的右子树 和 右子树的左子树是如何影响区间的合区间,然后查询操作一定要记得不要超过查询区间了。

#include<iostream>
#include<cstdio>
#define N 100005
using namespace std; int MAX(int i,int j){
if(i>j) return i;
return j;
}
int MIN(int i,int j){
if(i<j) return i;
return j;
}
struct Tree{
int l,r;
int lv,rv,mv; ///lv(rv)表示从最左(右)边起的最长连续递增子序列长度,mv表示该区间最大频率
}tree[*N];
int a[N];
void PushUp(int l,int r,int idx){
tree[idx].lv = tree[idx<<].lv; ///默认为左儿子的lv
tree[idx].rv = tree[idx<<|].rv; ///默认为右儿子的rv
tree[idx].mv = MAX(tree[idx<<].mv,tree[idx<<|].mv);///对于父区间的mv值,默认是先在左右子区间的mx值中取一个较大值
int mid=(l+r)>>;
int len = r-l+; ///区间长度
if(a[mid]<a[mid+]){ ///两边可以进行合并
///如果左子区间的lv等于左子区间的长度且可以延伸到右子区间,那么父区间的lv值等于左子区间
///的lv加上右子区间的lv,否则,父区间的lv值就是左子区间的lv值,对于右子区间,同理
if(tree[idx].lv==len-(len>>)) tree[idx].lv +=tree[idx<<|].lv;
if(tree[idx].rv==(len>>)) tree[idx].rv +=tree[idx<<].rv;
///果左右区间能够延续,则在当前值和左子区间的rv+右子区间的lv之间取较大值
tree[idx].mv = MAX(tree[idx].mv,tree[idx<<].rv+tree[idx<<|].lv);
}
}
void build(int l,int r,int idx){
tree[idx].l = l;
tree[idx].r = r;
if(l==r){
tree[idx].lv = tree[idx].rv = tree[idx].mv = ;
return;
}
int mid = (l+r)>>;
build(l,mid,idx<<);
build(mid+,r,idx<<|);
PushUp(l,r,idx);
} void update(int l,int r,int pos,int idx){ ///单点更新
if(l==r) {
return;
}
int mid=(l+r)>>;
if(pos<=mid) update(l,mid,pos,idx<<);
else update(mid+,r,pos,idx<<|);
PushUp(l,r,idx);
}
int query(int l,int r,int idx){
if(tree[idx].l>=l&&tree[idx].r<=r){
return tree[idx].mv;
}
int mid=(tree[idx].l+tree[idx].r)>>;
int ans = ;
///分别在左子区间和右子区间查找,结果分别为x,y,如果左右两个区间不能延续,
///那肯定是在x,y中找一个最大值
if(l<=mid) ans = MAX(ans,query(l,r,idx<<)); ///x
if(r>mid) ans = MAX(ans,query(l,r,idx<<|)); ///y
///如果能够延续,设两端延续区间长度为z,那么肯定是在 x,y,z找最大值,另外,对于左区间,我们要保证
///向左延续的区间(rv)肯定是在[l,mid]中的(不然超过我们要查询的区间了),所以长度必须要在 mid - l+1之内
///向右亦如此.
if(a[mid]<a[mid+]){
ans = MAX(ans,MIN(mid-l+,tree[idx<<].rv)+MIN(r-mid,tree[idx<<|].lv)); ///z
}
return ans;
}
int main()
{
int n,m;
int tcase;
scanf("%d",&tcase);
while(tcase--){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
build(,n,);
//for(int i=1;i<=n;i++) printf("%d ",tree[i].mv);
//printf("\n");
while(m--){
char s[];
scanf("%s",s);
if(s[]=='U'){
int b,c;
scanf("%d%d",&b,&c);
a[++b] = c; ///由于题目下标从0开始,所以++
update(,n,b,);
}else {
int b,c;
scanf("%d%d",&b,&c);
b++,c++;
printf("%d\n",query(b,c,));
}
}
}
return ;
}

hdu 3308(线段树区间合并)的更多相关文章

  1. hdu 3308 线段树 区间合并+单点更新+区间查询

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

  2. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

  3. HDU 3911 线段树区间合并

    北京赛区快了,准备袭击数据结构和图论.倒计时 18天,线段树区间合并.维护一个最长连续.. 题意:给一个01串,以下有一些操作,问区间最长的连续的1的个数 思路:非常裸的线段树区间合并 #includ ...

  4. hdu 1806(线段树区间合并)

    Frequent values Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

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

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

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

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

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

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

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

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

  9. hdu 3911 Black And White (线段树 区间合并)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3911 题意: 给你一段01序列,有两个操作: 1.区间异或,2.询问区间最长的连续的1得长度 思路: ...

随机推荐

  1. nodejs获取文件信息,判断是文件或目录

    var stat = fs.statSync(filename); console.log(stat) 输出 { dev: 0, ino: 0, mode: 33206, nlink: 1, uid: ...

  2. 34张史上最全IT架构师技术知识图谱 最新下载

    本文是笔者多年来积累和收集的知识技能图谱,小编极力推荐分享给身边的技术人儿,希望这份技术知识图谱能够帮助到每一位奋斗在技术路上的小伙伴. 下面是笔者多年来积累和收集的知识技能图谱,有的是笔者原创总结的 ...

  3. HTTP的特点?

    (1)HTTP是无连接: 无连接的含义是限制每次连接只处理一个请求.服务器处理完客户的请求,并收到客户的应答后,即断开连接.采用这种方式可以节省传输时间. (2)HTTP是媒体独立的: 这意味着,只要 ...

  4. bzoj 相似回文串 3350 3103 弦图染色+manacher

    相似回文串 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 143  Solved: 68[Submit][Status][Discuss] Descr ...

  5. bzoj 1106 [POI2007]立方体大作战tet 树状数组优化

    [POI2007]立方体大作战tet Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 821  Solved: 601[Submit][Status][ ...

  6. SQL Server2000安装教程图解

    sql2000安装教程图解... ================================= 第一部分:下载所需要的安装包: 可以自己在网上百度了之后下载--或是直接从我已打包好的群里下载 = ...

  7. JAVA--结果集已耗尽

    有两个可能 1.rs ,state和conn没有关闭 rs.close();  state.close();  conn.close(); if(rs!=null) rs.close;  if(sta ...

  8. 洛谷 P1044 栈

    题目背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈). 栈的重要性不言自明,任何 ...

  9. sqlserver xml转表 及(cross apply与outer apply)

    一. 需求是需要把','分割的字符串转为表,便于做关联查询,于是发现可以通过xml转为表,如下: declare @XXX xml set @XXX = ' <v> <aa>1 ...

  10. 【BZOJ4517】【SDOI2016】排列计数 [数论]

    排列计数 Time Limit: 60 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 求有多少种长度为 n 的序列 A, ...