HDU 3308 LCIS (线段树&&最长递增子序列长度)
来源:互联网 发布:阿里云主机怎么使用 编辑:程序博客网 时间:2024/06/05 03:45
传送门 :http://acm.hdu.edu.cn/showproblem.php?pid=3308
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
题目大意:
给你n个数,m个操作。操作有两种:1.U x y 将数组第x位变为y 2. Q x y 问数组第x位到第y位连续最长子序列的长度。对于每次询问,输出一个答案
目前做的最难一道线段树题了, 比较弱,比较弱
这是一道比较典型的 单点更新,区间合并的题目
建立线段树还是常规建法 ,不过这里建树时,直接在外部输入每个点的值
建树主要在于更新 ls, rs ,no的值 (ls代表区间递增前缀长度, rs代表递增区间后缀长度, no代表最大的递增子序列长度 ) ###(重点)
难处理的在于 更新节点时 要处理 最长递增子序列的长度 ,可以分为以下2种情况
1.如果左区间的最右边的值小于右区间最左边的值,则有一个待定答案是左儿子的右区间+右儿子的左区间
2.如果不符合第一个条件,则有一个待定答案是左区间最大值和右区间最大值中较大的那一个。
有一点要特别注意:如果当前区间中所有的值都符合上升序列,那么更新它的父节点时,它可以加上其他区间的边界值而进行扩充
举个栗子 画个演示图
求3 1 2 4 5 的最大递增子序列长度(显示补图)
code:
#include <iostream>//#include <bits/stdc++.h>#include <string.h>#include <cstdio>#include <algorithm>using namespace std;#define lchild left, mid, root<<1#define rchild mid+1, right, root<<1|1#define maxn 200000int a[maxn<<2]; ///a数组存储值int ls[maxn<<2],rs[maxn<<2],no[maxn<<2]; ///ls代表区间前缀长度, rs代表区间后缀长度, no代表最大的子序列长度int x,y;void update(int left, int right, int root){ int mid=left+right>>1; ls[root]=ls[root<<1];rs[root]=rs[root<<1|1]; ///向上更新当前的ls, rs 和 no no[root]=max(no[root<<1],no[root<<1|1]); if(a[mid]<a[mid+1]) ///如果a[mid]<a[mid+1]即2个区间可以合并 { if(ls[root]==mid-left+1) ///判断从left到mid是完整的递增 ls[root]+=ls[root<<1|1]; if(rs[root]==right-mid) ///判断从mid+1到right是完整的递增 rs[root]+=rs[root<<1]; no[root]=max(no[root],ls[root<<1|1]+rs[root<<1]); ///左区间的后缀加上右区间的前缀即合并后的no值 }}void build(int left, int right, int root){ if (left==right) { no[root]=ls[root]=rs[root]=1; ///找到叶子节点 初始化 return; } int mid = (left+right)>>1; build(lchild); build(rchild); update(left, right, root);}void operate(int left, int right, int root){ if (left==right) { return; } int mid = (left+right)>>1; if (x<=mid) operate(lchild); else operate(rchild); update(left, right, root);}int inquery(int l, int r, int left, int right, int root){ //cout<<l<<" "<<r<<" "<<left<<" "<<right<<" "<<sum[root]<<endl; if (l<=left&&r>=right) return no[root]; int ans; int mid = (left+right)>>1; if (r<=mid) ///右边界小于重点,只用返回左边计算的值即可 return inquery(l,r,lchild); if (l>mid) return inquery(l,r,rchild); int t1=inquery(l,r,lchild); ///左右边界分开查询 int t2=inquery(l,r,rchild); ans=max(t1,t2); if(a[mid]<a[mid+1]) ans=max(ans,(min(ls[root<<1|1],r-mid)+min(rs[root<<1],mid+1-l))); return ans;}int main(){ int N; int m,n; scanf("%d",&N); while (N--) { scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) scanf("%d",&a[i]); build(1,n,1); while (m--) { char str[3]; getchar(); scanf("%s",str); //cout<<"!!!"<<str<<endl; scanf("%d%d",&x,&y); x++; if (str[0]=='Q') { y++; int ans; ans = inquery(x,y,1,n,1); printf("%d\n",ans); } else if (str[0]=='U') { a[x] = y; operate(1,n,1); } } } return 0;}
- HDU 3308 LCIS (线段树&&最长递增子序列长度)
- HDU 3308——LCIS(线段树,区间合并,最长连续递增子序列)
- HDU ACM 3308 LCIS->最长连续递增子序列->线段树+区间合并+单点修改
- HDU 3308 LCIS(线段树+区间合并+最长递增连续子串)
- hdoj 3308 LCIS 【线段树单点更新 + 区间合并】【求解最长递增序列 的长度】
- HDU 3308 LCIS(最长连续上升子序列)(线段树区间合并)
- uestc 1425 Another LCIS(线段树 最长递增序列)
- HDU 3308 LCIS 最长连续递增序列+数据结构+线段树+单点更新
- hdu_3308 LCIS 区间合并 求最长递增子序列长度
- hdu 3308 LCIS(线段树 最长连续递增)
- HDU 3308 LCIS(线段树,连续递增子)
- 3308 LCIS(线段树水题&最长连续递增序列)
- hdu 1423 Greatest Common Increasing Subsequence(最长公共递增子序列lcis)
- HDU 3308 LCIS(最长连续上升子序列)
- 线段树区间合并+最长连续递增子序列——HDU 3308
- hdu 1257(最长递增子序列)
- HDU 3308 最长上升连续子序列 (线段树)
- hdu 3564 线段树+dp(最大递增子序列)
- 数据结构带着复杂度跑来了
- 小demo
- 二叉树遍历递归非递归,前序,中序,后序
- LightGBM算法的特别之处
- Chrome在Mac上的跨域设置
- HDU 3308 LCIS (线段树&&最长递增子序列长度)
- 浅析前端技术体系
- Windows 下Maven安装配置(本地仓库配置)
- VSCode
- 使用FileUtils简化你的文件操作
- java泛型方法实现数值类型加法
- SuperMap iCloudManager常见问题解答集锦(一)
- 定义seekbar样式
- 泛型