最大连续区间(HDU-1540)
HDU1540
线段树最大连续区间。
给定长度为n的数组,m次操作。
操作D,删除给定节点。
操作R,恢复最后一个删除的节点。
操作Q,询问给定节点的最大连续区间
维护三个值,区间的最大左连续区间,最大右连续区间,最大连续区间
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
using namespace std;
typedef long long ll;
const int maxn = 50000 + 5;
#define lson l,m,st<<1
#define rson m+1,r,st<<1|1
int treelmax[maxn<<2];
int treermax[maxn<<2];
int len[maxn<<2];
void build(int l,int r,int st)
{
len[st]=r-l+1;
if(l==r)
{
treelmax[st]=1;treermax[st]=1;
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
treelmax[st]=len[st]; //初始化的值全为区间长度
treermax[st]=len[st];
}
void UpdataDes(int x,int l,int r,int st) //破坏
{
if(l==x&&r==x)
{
treelmax[st]=0; treermax[st]=0;len[st]=0; return;
}
int m=(l+r)>>1;
if(x<=m) UpdataDes(x,lson);
else UpdataDes(x,rson); //if(x>m)
treelmax[st]=treelmax[st<<1]==(m-l+1)?treelmax[st<<1]+treelmax[st<<1|1]:treelmax[st<<1]; //判断左儿子的最大左连续区间是否等于左儿子区间长度,如果等于,那么父亲的最大左连续区间就等于左儿子的区间长度加上右儿子右最大左区间连续长度
treermax[st]=treermax[st<<1|1]==(r-m)?treermax[st<<1|1]+treermax[st<<1]:treermax[st<<1|1];
len[st]=max(max(treelmax[st<<1],treermax[st<<1|1]),treermax[st<<1]+treelmax[st<<1|1]);
//父节点的最大连续长度等于 左儿子最大左连续区间 右儿子最大右连续区间 左儿子最大右连续区间加上右儿子最大左连续区间 中的最大值
}
void UpdataRec(int x,int l,int r,int st) //修复
{
if(l==x&&r==x)
{
treelmax[st]=1; treermax[st]=1;len[st]=1; return ;
}
int m=(l+r)>>1;
if(x<=m) UpdataRec(x,lson);
else UpdataRec(x,rson); //if(x>m)
treelmax[st]=treelmax[st<<1]==(m-l+1)?treelmax[st<<1]+treelmax[st<<1|1]:treelmax[st<<1];
treermax[st]=treermax[st<<1|1]==(r-m)?treermax[st<<1|1]+treermax[st<<1]:treermax[st<<1|1];
len[st]=max(max(treelmax[st<<1],treermax[st<<1|1]),treermax[st<<1]+treelmax[st<<1|1]);
//pushup;
}
int query(int x,int l,int r,int st)
{
if(l==r||len[st]==0||len[st]==r-l+1)
return len[st];
int m=(l+r)>>1;
if(x<=m) //x在左儿子区间内
{
if(x>=m-treermax[st<<1]+1) //x在左儿子的右连续区间内
return treermax[st<<1]+treelmax[st<<1|1]; //左儿子右连续
//return len[st<<1];
else //x在左儿子的左连续区间内
return query(x,lson);
}
else //x在右儿子区间内
{
if(x<m+1+treelmax[st<<1|1]) //x在右儿子的左连续区间
return treermax[st<<1]+treelmax[st<<1|1]; //左儿子的右连续加上右儿子的左连续
//return len[st<<1|1];
else //x在右儿子的右连续区间
return query(x,rson);
}
}
int main()
{
int n,m;
char ope[5];
int x;
while(scanf("%d%d",&n,&m)!=EOF)
{
build(1,n,1);
stack<int> destroy;
while(m--)
{
scanf("%s",ope);
if(ope[0]=='D')
{
scanf("%d",&x);
UpdataDes(x,1,n,1);
destroy.push(x);
}
else if(ope[0]=='R')
{
if(destroy.empty()) continue;
x=destroy.top();
UpdataRec(x,1,n,1);
destroy.pop();
}
else
{
scanf("%d",&x);
printf("%d\n",query(x,1,n,1));
}
}
}
return 0;
}
最大连续区间(HDU-1540)的更多相关文章
- HDU 1540 Tunnel Warfare(最长连续区间 基础)
校赛,还有什么途径可以申请加入ACM校队? Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/ ...
- HDU 1540 Tunnel Warfare
HDU 1540 思路1: 树状数组+二分 代码: #include<bits/stdc++.h> using namespace std; #define ll long long #d ...
- hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】
Tunnel Warfare Time Limit: 4000/2000 MS ...
- HDU 1540 / POJ 2892 Tunnel Warfare (单点更新,区间合并,求包含某点的最大连续个数)
题意:一条线上有n个点,D x是破坏这个点,Q x是表示查询x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 思路:这题的关键是查询. 将被毁的村庄看成空位,当查询某个点的时候,如果我们知道它左 ...
- Tunnel Warfare HDU 1540 区间合并+最大最小值
Tunnel Warfare HDU 1540 区间合并+最大最小值 题意 D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 题解思路 参考的大佬博客 这里 ...
- E - Tunnel Warfare HDU - 1540 F - Hotel G - 约会安排 HDU - 4553 区间合并
E - Tunnel Warfare HDU - 1540 对这个题目的思考:首先我们已经意识到这个是一个线段树,要利用线段树来解决问题,但是怎么解决呢,这个摧毁和重建的操作都很简单,但是这个查询怎么 ...
- I - Tunnel Warfare HDU - 1540 线段树最大连续区间
题意 :一段区间 操作1 切断点 操作2 恢复最近切断的一个点 操作3 单点查询该点所在最大连续区间 思路: 主要是push_up : 设区间x 为母区间 x<<1 ,x< ...
- Tunnel Warfare HDU - 1540 (线段树处理连续区间问题)
During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast a ...
- hdu 1540 Tunnel Warfare (线段树,维护当前最大连续区间)
Description During the War of Resistance Against Japan, tunnel warfare was carried out extensively i ...
- Tunnel Warfare HDU - 1540(线段树最长连续区间)
题意: 一条线上的点,D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 解析: 线段树结点 设置一个 lq记录区间左端点开始的最大连续个数, rq ...
随机推荐
- Python初识函数
Python初识函数 函数理论篇 什么是函数 在编程语言中的函数不同于数学中的函数.不管是数学上的函数还是编程语言中的函数都是为了完成特定的某一功能而诞生的,他们的区别在于: 1.数学中的函数当输入的 ...
- Python3-hashlib模块-加密算法之安全哈希
Python3中的hashlib模块提供了多个不同的安全哈希算法的通用接口 hashlib模块代替了Python2中的md5和sham模块,使用这个模块一般分为3步 1.创建一个哈希对象,使用哈希算法 ...
- Myeclipse启动WebLogic 总是报账号密码无效<Authentication denied: Boot identity not valid
在MyEclipse下配置了Weblogic 11后,每次启动从报错: Critical> 看了下描述,是用户名及密码什么的问题,我想起来,配置Weblogic 的域的时候将密码改成了12345 ...
- 03 . Shell数组和函数
Shell数组 简介 数组中可以存放多个值.Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似). 与大部分编程语言类似,数组元素的下标由0开始. S ...
- Zookeeper Watcher 流程分析(结合源码)
概述 ZK提供了分布式数据的发布/订阅功能,一个典型的发布/订阅模型系统定义了一种一对多的订阅关系,能够让多个订阅者同时监听某个主题对象,当这个主题对象自身状态发生变化时,会通知所有的订阅者.在ZK中 ...
- 八.django日志配置
Django 日志 Django 使用Python 内建的logging 模块打印日志,Python 的logging 配置由四个部分组成: 记录器 —— Logger 处理程序 —— Handler ...
- jQurey zTree Demo 3.5
https://jeesite.gitee.io/front/jquery-ztree/3.5/demo/cn/index.html
- Javascript 中 数组遍历 forin和forof 的区别
定义一个数组 let array = [1, 2, 3, 4]; for (let a in array){ console.log("遍历a的值 "+a+"”,数组中的 ...
- 前端同学经常忽视的一个 JavaScript 面试题
题目 function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = funct ...
- (二)LVS介绍
LVS分3种模式 (a)NAT(网络地址映射):通过网络地址转换的方法来实现调度 优点:支持所有操作系统及私有网络,且只需一个公网 IP 地址 缺点:用户请求和响应报文都必须 ...