LCIS HDU - 3308 (线段树区间合并)
LCIS HDU - 3308
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].
InputT in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=10 5).
The next line has n integers(0<=val<=10 5).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=10 5)
OR
Q A B(0<=A<=B< n).
OutputFor 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
个人思路:这道题应该算是线段树区间合并的板子题,关键就是明确区间合并时的逻辑关系就可以了
我因为忽略区间内的最长连续上升序列有可能由子区间的区间内连续上升序列得到而错了好几次
//线段树区间合并
//关键:明确相邻区间合并时候的逻辑关系
#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define mem(a,x) memset(a,x,sizeof(a))
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid + 1,r
#define P pair<int,int>
#define ull unsigned long long
using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
const int inf = 0x3f3f3f3f; struct node
{
int l,r;
int left ,right ,mid;
int maxx;
}tree[maxn << ]; int n,m;
int arr[maxn]; void Pushup(int rt)
{
tree[rt].left = tree[rt << ].left;
tree[rt].right = tree[rt << |].right;
bool flag = arr[tree[rt << |].l] > arr[tree[rt << ].r]; if(tree[rt << |].right == tree[rt << |].r - tree[rt << |].l + && flag)
{
tree[rt].right += tree[rt << ].right;
}
// 合并以左端点为头的最长序列 if(tree[rt << ].left == tree[rt << ].r - tree[rt << ].l + && flag)
{
tree[rt].left += tree[rt << |].left;
}
// 合并以右端点为尾的最长序列 if(arr[tree[rt << |].l] > arr[tree[rt << ].r])
{
tree[rt].mid = tree[rt << ].right + tree[rt << |].left;
}
else
{
tree[rt].mid = max(tree[rt << ].right , tree[rt << |].left);
}
tree[rt].mid = max(tree[rt].mid , max(tree[rt << ].mid,tree[rt << |].mid));
// 获得区间内的最长序列:可能由子区间构成 也可能从子区间得到
tree[rt].maxx = max(tree[rt].mid, max(tree[rt].left , tree[rt].right));
} void build(int rt ,int l ,int r)
{
tree[rt].l = l , tree[rt].r = r;
if(l == r)
{
tree[rt].left = tree[rt].right = tree[rt].maxx = tree[rt].mid = ;
return;
}
int mid = l + r >> ;
build(lson);
build(rson);
Pushup(rt);
} void update(int rt ,int k ,int v)
{
if(tree[rt].l == k && tree[rt].r == k)
{
arr[k] = v;
tree[rt].left = tree[rt].right = tree[rt].maxx = tree[rt].mid = ;
return;
}
int mid = tree[rt].l + tree[rt].r >> ;
if(mid >= k)
{
update(rt << , k , v);
}
else
{
update(rt << | , k , v);
}
Pushup(rt);
} int query(int rt , int l ,int r)
{
if(tree[rt].l == l && tree[rt].r == r)
{
return tree[rt].maxx;
}
int mid = tree[rt].l + tree[rt].r >> ;
if(mid >= r)
{
return query(rt << , l , r);
}
else if(mid < l )
{
return query(rt << | , l , r);
}
else
{
int m = min(mid - l + , tree[rt << ].right) + min(r - mid , tree[rt << |].left);
int left = query(rt<< ,l ,mid);
int right = query(rt << | , mid + , r);
if(arr[tree[rt << ].r] < arr[tree[rt << |].l])
{
return max(m,max(left , right));
}
else
{
return max(left , right);
}
}
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
//mem(arr,0);
scanf("%d %d",&n,&m);
for(int i = ; i <= n ; ++ i)
{
scanf("%d",&arr[i]);
}
build(,,n);
while(m -- )
{
char judge;
int l,r;
scanf(" %c %d %d",&judge ,&l , &r);
if(judge == 'U')
{
update(,l + ,r);
}
else
{
printf("%d\n",query(,l + , r + ));
}
}
}
return ;
}
AC代码
一个从很久以前就开始做的梦
LCIS HDU - 3308 (线段树区间合并)的更多相关文章
- hdu 3308(线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 3308 线段树 区间合并+单点更新+区间查询
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
- HDU 3911 线段树区间合并
北京赛区快了,准备袭击数据结构和图论.倒计时 18天,线段树区间合并.维护一个最长连续.. 题意:给一个01串,以下有一些操作,问区间最长的连续的1的个数 思路:非常裸的线段树区间合并 #includ ...
- hdu 1806(线段树区间合并)
Frequent values Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
- HDU 3308 (线段树区间合并)
http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作 : 1 修改 单点 a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...
- hdu 3911 Black And White (线段树 区间合并)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3911 题意: 给你一段01序列,有两个操作: 1.区间异或,2.询问区间最长的连续的1得长度 思路: ...
- hdu-3308 LCIS (线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
随机推荐
- Job for nginx.service failed because the control process exited with error code. See “systemctl stat
启动nginx服务时如果遇到这个错误 Job for nginx.service failed because the control process exited with error code. ...
- 提升Windows系统舒适度软件
1.Geek Uninstaller 卸载软件 2.PotPlayer 无广告播放器
- a标签-伪类
a:link {color: #FF0000} /* 未访问的链接 */ a:visited {color: #00FF00} /* 已访问的链接 */ a:hover {color: #FF00FF ...
- golang调用CertUtil获取文件md5
func getFileMD5(fileName string) string { cmd := exec.Command("cmd", "/C", " ...
- yeoman 介绍、安装 和 使用
一.介绍.安装 1, 是什么 Yeoman其实是3个工具的总和: ü yo --- 脚手架,自动生成工具 ü Grunt.gulp --- 构建工具 (最初只有grunt,后面gulp火了添加进来 ...
- Redis 详解 (一) redis的简介和安装
目录 1.Redis 的简介 2.Redis 下载 3.安装环境 4.编译安装 5.启动Redis 6.关闭Redis 7.注意事项 工作中一直在用 Redis,但是一直没有进行系统的总结,这个系列的 ...
- Hadoop完全高可用集群安装
架构图(HA模型没有SNN节点) 用vm规划了8台机器,用到了7台,SNN节点没用 NN DN SN ZKFC ZK JNN RM NM node1 * * node2 * ...
- centos7如何修改IP地址
步骤1:使用vi编辑 /etc/sysconfig/network-scripts/目录下的ifcfg-ens160 配置文件 [root@model ~]# [root@model ~]# vi / ...
- 【转】美团 MySQL 数据实时同步到 Hive 的架构与实践
文章转载自公众号 美团技术团队 , 作者 萌萌 背景 在数据仓库建模中,未经任何加工处理的原始业务层数据,我们称之为ODS(Operational Data Store)数据.在互联网企业中,常见的 ...
- Django 数据库配置
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'books', #你的数据库名称 'USER': ' ...