题目大意:给你n个数,m个操作。

有两种操作:

1.U x y 将数组第x位变为y

2. Q x y 问数组第x位到第y位连续最长子序列的长度。

对于每次询问,输出连续最长子序列的长度

思路:用线段树维护上升序列,每个端点维护:左边连续递增的len,右边连续递增的len,中间连续递增的len,左边val,右边val,和目前的len。然后不断更新即可。

注意:如果左区间的最右边的值小于右区间最左边的值,则有一个待定答案是左儿子的右区间+右儿子的左区间

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
/*
①记录本身内部的序列长度
②要将区间合并的时候,rightson的left区间和leftson的right区间判断条件以后再合并。
如果合并区间是对于两端的值
*/
const int maxn = 1e5 + ;
struct Tree{
int leftlen, rightlen, midlen, leftval, rightval, len;
}tree[maxn << ];
int n, m; inline void pushup(int o){
int lb = o << , rb = o << | ;
int lbval = tree[lb].rightval, rbval = tree[rb].leftval;
bool flag = false;
tree[o].midlen = max(tree[lb].rightlen, max(tree[rb].leftlen, max(tree[lb].midlen, tree[rb].midlen)));
if (lbval < rbval) {
flag = true;
tree[o].midlen = max(tree[lb].rightlen + tree[rb].leftlen, tree[o].midlen);
} tree[o].leftlen = tree[lb].leftlen;
if (tree[lb].rightlen == tree[lb].len && flag) tree[o].leftlen = tree[o].midlen; tree[o].rightlen = tree[rb].rightlen;
if (tree[rb].leftlen == tree[rb].len && flag) tree[o].rightlen = tree[o].midlen;
tree[o].leftval = tree[lb].leftval, tree[o].rightval = tree[rb].rightval;
} void buildtree(int l, int r, int o){
tree[o].len = r - l + ;
if (l == r){
int val; scanf("%d", &val);
tree[o].leftlen = tree[o].rightlen = tree[o].midlen = ;
tree[o].leftval = tree[o].rightval = val;
return ;
}
int mid = (l + r) / ;
if (l <= mid) buildtree(l, mid, o << );
if (r > mid) buildtree(mid + , r, o << | );
pushup(o);
//printf("l = %d r = %d leftlen = %d rightlen = %d midlen = %d\n", l, r, tree[o].leftlen, tree[o].rightlen, tree[o].midlen);
} void update(int pos, int val, int l, int r, int o){
if (pos == l && pos == r){
tree[o].leftval = tree[o].rightval = val; return ;
}
int mid = (l + r) / ;
if (pos <= mid) update(pos, val, l, mid, o << );
if (pos > mid) update(pos, val, mid + , r, o << | );
pushup(o);
} int query(int ql, int qr, int l, int r, int o){
int ans = ;
if (ql <= l && qr >= r){
ans = max(ans, max(tree[o].leftlen, max(tree[o].rightlen, tree[o].midlen)));
return ans;
}
int mid = (l + r) / ;
int t1 = -, t2 = -;
if (mid >= ql){
t1 = query(ql, qr, l, mid, o << );
}
if (mid < qr){
t2 = query(ql, qr, mid + , r, o << | );
}
ans = max(ans, max(t1, t2));
///如果左区间的最右边的值小于右区间最左边的值,则有一个待定答案是左儿子的右区间+右儿子的左区间
if (tree[o << ].rightval < tree[o << | ].leftval && t1 > && t2 > ){
t1 = min(tree[o << ].rightlen, mid - ql + ) + min(tree[o << | ].leftlen, qr - mid);
ans = max(ans, t1);
}
return ans;
} int main(){
int t; cin >> t;
while (t--){
scanf("%d%d", &n, &m);
buildtree(, n, );
for (int i = ; i <= m; i++){
char ch[]; int a, b;
scanf("%s%d%d", ch, &a, &b);
if (ch[] == 'U'){
update(a + , b, , n, );
}
else {
printf("%d\n", query(a + , b + , , n, ));
}
}
}
return ;
}

关键:

感觉和以前的一题CF很像,忘了是哪里的了......

5W次单点修改,求最长的连续上升子序列 HDU 3308的更多相关文章

  1. hdu 3308 线段树,单点更新 求最长连续上升序列长度

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

  2. 求最长非降(递增)子序列LIS的长度,及注意事项

    非降序列(Increasing Sequence)例如: (1) 完全递增型序列:S={1,3,6,7,9} (2) 部分存在等于的序列:S={1,3,3,6,9} S的非降子序列:由原序列S的元素组 ...

  3. UVA11572-Unique Snowflakes-(最长不同连续子序列)

    题意:给n个数,求最长不同连续子序列.n<=1e6. 解题过程: 1.记录数据存于数组 2.用左右指针l和r指向这段连续区间 3.右指针往右走,如果遇到没有存在于set集合的数就插入集合 否则左 ...

  4. HDU 4745 Two Rabbits(区间DP,最长非连续回文子串)

    Two Rabbits Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total ...

  5. 【JZOJ4889】【NOIP2016提高A组集训第14场11.12】最长公共回文子序列

    题目描述 YJC最近在学习字符串的有关知识.今天,他遇到了这么一个概念:最长公共回文子序列.一个序列S,如果S是回文的且分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已 ...

  6. pta 习题集 5-5 最长连续递增子序列 (dp)

    给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长的连续递增子序列.例如,(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8). 输入格式: 输入第1行给出正整数n ...

  7. BNUOJ 4215 最长公共连续子序列

    最长公共连续子序列 Time Limit: 1000ms Memory Limit: 65536KB   64-bit integer IO format: %lld      Java class ...

  8. HDU-1754-I Hate It-线段树-求区间最值和单点修改

    开学新拉的题目,老题重做,思路会稍微比之前清晰,不过这也算是一点点进步了. 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现 ...

  9. hdu_2668 Daydream O(n)求最长不重复子串

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

随机推荐

  1. mysql You can't specify target table 'xxx' for update in FROM clause

    含义:您不能在子句中为更新指定目标表'xxx'. 错误描述:删除语句中直接含select,如下: DELETE FROM meriadianannotation WHERE SeriesID IN ( ...

  2. Linux 环境下svn 服务器搭建

    可使用自己下载的svn安装包,但要安装相关依赖包,yum 安装源提供的稳定版本svn 1.yum -y install subversion 2.创建本地库 mkdir -p /var/svn svn ...

  3. “我爱淘”第二冲刺阶段Scrum站立会议5

    完成任务: 完成了登录界面的实现,可以按照数据库中的用户名密码进行登录,. 计划任务: 在客户端实现分类功能,通过学院的分类查看书籍. 遇到问题: 再登录上了之后,并且保存密码,但是点击退出当前账号这 ...

  4. C语言的知识与能力的自评

    1.我希望将来上班的地方是自己所感兴趣的,正在寻找自己感兴趣的,并且正在普及IT行业的相关知识. 2.我认为学习就是一个自我成长和自我提升以及认识世界的方法,学习的作用是可以不断的提升对这个世界的认识 ...

  5. EF动态排序

    转载的代码,改天再研究 public PageData<T> FindAll(int PageIndex, int PageSize, Expression<Func<T, b ...

  6. ElasticSearch API 简要介绍

    调用其API会返回很多信息,例如集群的信息,节点的信息等 检查集群的状态----Restful API说明 1:检查集群状态信息 2:管理集群 3:执行 增删改查 命令 4:执行高级命令 Restfu ...

  7. Node.js系列——(4)优势及场景

    背景 之前几篇系列文章简单介绍了node.js的安装配置及基本操作: Node.js系列--(1)安装配置与基本使用 Node.js系列--(2)发起get/post请求 Node.js系列--(3) ...

  8. Navicat Premium_11.2.7简体中文版 破解版本 windows版本

    亲测可用 自己一直在用的 https://pan.baidu.com/s/1VVKKQoIKVB0BgNXBK4YTrQ

  9. Java容器深入浅出之数组

    写在前面 关于Java的学习,特别是对于非计算机专业的同学来说,我总是主张从实践中来,到实践中去的学习方法.Java本身是一门应用性特别强的高级编程语言,因此如果能在基于实际开发的经验基础上,对Jav ...

  10. PL/SQL中复制粘贴表结构信息

    1.打开下图中的Tables文件夹 2.查找要找的表 3.右键单击找到的表—>Describe 4.复制所需的数据到EXCEL表中