题目大意:给你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. 软件工程-东北师大站-第四次作业PSP

    1.本周PSP 2.本周进度条 3.本周累计进度图 代码累计折线图 博文字数累计折线图 4.本周PSP饼状图

  2. Beta版软件使用说明

    1引言 1 .1编写目的 编写本使用说明的目的是充分叙述本软件所能实现的功能及其运行环境,以便使用者了解本软件的使用范围和使用方法,并为软件的维护和更新提供必要的信息. 1 .2参考资料 1 .3术语 ...

  3. .net学习-扩展

    uwp uwpapp-斗鱼,微信等 云和移动优先 远程桌面连接设置 teamviewer V8内核 Node.js javascript 事件循环 express框架 bootstrap NoSQL ...

  4. java程序连接MySQL数据库

    驱动程序:mysql-connector-java-5.1.7-bin.jar. 程序示例如下: package commonProject; import java.sql.Connection; ...

  5. MySQL 忘记root密码怎么办

    前言:记住如果忘记root密码,在启动MySQL的时候,跳过查询授权表就ok了. 对于RedHat 6 而言 (1)启动mysqld 进程时,为其使用:--skip-grant-tables --sk ...

  6. Matlab里面.M文件不能运行,预期的图像也显示不出来的一个原因

    matlab中function函数的函数名与保存的文件名需要一样: 函数名是GAconstrain,文件名保存成GAconstrain.m,不要使用复制时候产生副本GAconstrain(1).m.

  7. [翻译]API Guides - Service

    官方文档原文地址:http://developer.android.com/guide/components/services.html Service是应用程序组件之一,它并不提供一个用户界面,可以 ...

  8. mysql 、慢查询、到底如何玩

    在项目开发中,那些开发大佬经常会写出一些SQL语句,一条糟糕的SQL语句可能让你测试的整个程序都非常慢,超过10秒的话,我觉得一般用户就会选择关闭网页,如何优化SQL语句将那些运行时间 比较长的SQL ...

  9. 深入理解JVM一类加载器原理

    我们知道我们编写的java代码,会经过编译器编译成字节码文件(class文件),再把字节码文件装载到JVM中,映射到各个内存区域中,我们的程序就可以在内存中运行了.那么字节码文件是怎样装载到JVM中的 ...

  10. 【刷题】LOJ 6041 「雅礼集训 2017 Day7」事情的相似度

    题目描述 人的一生不仅要靠自我奋斗,还要考虑到历史的行程. 历史的行程可以抽象成一个 01 串,作为一个年纪比较大的人,你希望从历史的行程中获得一些姿势. 你发现在历史的不同时刻,不断的有相同的事情发 ...