5W次单点修改,求最长的连续上升子序列 HDU 3308
题目大意:给你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的更多相关文章
- hdu 3308 线段树,单点更新 求最长连续上升序列长度
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- 求最长非降(递增)子序列LIS的长度,及注意事项
非降序列(Increasing Sequence)例如: (1) 完全递增型序列:S={1,3,6,7,9} (2) 部分存在等于的序列:S={1,3,3,6,9} S的非降子序列:由原序列S的元素组 ...
- UVA11572-Unique Snowflakes-(最长不同连续子序列)
题意:给n个数,求最长不同连续子序列.n<=1e6. 解题过程: 1.记录数据存于数组 2.用左右指针l和r指向这段连续区间 3.右指针往右走,如果遇到没有存在于set集合的数就插入集合 否则左 ...
- HDU 4745 Two Rabbits(区间DP,最长非连续回文子串)
Two Rabbits Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total ...
- 【JZOJ4889】【NOIP2016提高A组集训第14场11.12】最长公共回文子序列
题目描述 YJC最近在学习字符串的有关知识.今天,他遇到了这么一个概念:最长公共回文子序列.一个序列S,如果S是回文的且分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已 ...
- pta 习题集 5-5 最长连续递增子序列 (dp)
给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长的连续递增子序列.例如,(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8). 输入格式: 输入第1行给出正整数n ...
- BNUOJ 4215 最长公共连续子序列
最长公共连续子序列 Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld Java class ...
- HDU-1754-I Hate It-线段树-求区间最值和单点修改
开学新拉的题目,老题重做,思路会稍微比之前清晰,不过这也算是一点点进步了. 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现 ...
- hdu_2668 Daydream O(n)求最长不重复子串
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2668 Daydream Time Limit: 2000/1000 MS (Java/Others) ...
随机推荐
- Android 7.1.1 又出幺蛾子了 —— 再谈 Android 上的 Wifi 连接
在之前的博客文章中,我写了点在 Android 6 系统中连接到指定名称的 Wifi 的体验.然而,在 Android 7 中,有一些东西又变化了.另外就是在那篇文章中我说要提供代码,结果拖到这篇文章 ...
- UVALive - 6893 The Big Painting 字符串哈希
题目链接: http://acm.hust.edu.cn/vjudge/problem/129730 The Big Painting Time Limit: 5000MS 题意 给你一个模板串和待匹 ...
- ImportError: No module named examples.tutorials.mnist
Traceback (most recent call last): File "nearest_neighbor.py", line 14, in <module> ...
- erlang驱动使用mysql-otp
Magnus Ahltorp的Mysql Driver里面介绍emysql的缺陷: 1. 隔离不够好, 2.不能伸缩 mysql-otp使用1个进程1个mysql连接,隔离得很好.推荐使用. mysq ...
- 【week10】psp
项目 内容 开始时间 结束时间 中断时间 净时间 2016/11/19(星期六) 写博客 吉林一日游规格说明书 10:30 15:10 20 260 2016/11/20(星期日) 看论文 磷酸化+三 ...
- HDU4759_Poker Shuffle
这是一个很好的题目,来自2013长春网赛. 题目的意思是给你2^N张扑克牌,每次洗牌前分别把从下开始数为奇数和偶数的牌分别拿出来放在一堆,两堆可以任意一个放在上面. 现在问你是否存在一种情况使得经过若 ...
- bzoj1031-字符加密
环的问题,经典方法倍长串,求出后缀数组,扫一次sa,如果sa[i]小于等于n,那么就输出这个字符串结尾的位置(即s[sa[i]+n-1]). 代码 #include<cstdio> #in ...
- MySQL事务提交过程
一.MySQL事务提交过程(一) MySQL作为一种关系型数据库,已被广泛应用到互联网中的诸多项目中.今天我们来讨论下事务的提交过程. 由于mysql插件式存储架构,导致开启binlog后,事务提交实 ...
- Spring Boot系列教程五:使用properties配置文件实现多环境配置
一.前言 实际项目开发过程中会用到多个环境,比如dev,test,product环境,不同的环境可能使用不同参数,为便于部署提高效率,本篇主要通过properties配置文件来实现多环境的配置. 二. ...
- 常州day2
Task1 为了测试小 W 的数学水平,果果给了小 W N 个点,问他这 N 个点能构成的三角形个数. 对于 100%的数据:N<=100,保证任意两点不重合,坐标<=10000 恶心题( ...