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)的更多相关文章

  1. HDU 1540 Tunnel Warfare(最长连续区间 基础)

    校赛,还有什么途径可以申请加入ACM校队?  Tunnel Warfare Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/ ...

  2. HDU 1540 Tunnel Warfare

    HDU 1540 思路1: 树状数组+二分 代码: #include<bits/stdc++.h> using namespace std; #define ll long long #d ...

  3. hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】

    Tunnel Warfare                                                             Time Limit: 4000/2000 MS ...

  4. HDU 1540 / POJ 2892 Tunnel Warfare (单点更新,区间合并,求包含某点的最大连续个数)

    题意:一条线上有n个点,D x是破坏这个点,Q x是表示查询x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 思路:这题的关键是查询. 将被毁的村庄看成空位,当查询某个点的时候,如果我们知道它左 ...

  5. Tunnel Warfare HDU 1540 区间合并+最大最小值

    Tunnel Warfare HDU 1540 区间合并+最大最小值 题意 D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点. 题解思路 参考的大佬博客 这里 ...

  6. E - Tunnel Warfare HDU - 1540 F - Hotel G - 约会安排 HDU - 4553 区间合并

    E - Tunnel Warfare HDU - 1540 对这个题目的思考:首先我们已经意识到这个是一个线段树,要利用线段树来解决问题,但是怎么解决呢,这个摧毁和重建的操作都很简单,但是这个查询怎么 ...

  7. I - Tunnel Warfare HDU - 1540 线段树最大连续区间

    题意  :一段区间  操作1 切断点 操作2 恢复最近切断的一个点 操作3 单点查询该点所在最大连续区间 思路:  主要是push_up :  设区间x 为母区间  x<<1 ,x< ...

  8. Tunnel Warfare HDU - 1540 (线段树处理连续区间问题)

    During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast a ...

  9. hdu 1540 Tunnel Warfare (线段树,维护当前最大连续区间)

    Description During the War of Resistance Against Japan, tunnel warfare was carried out extensively i ...

  10. Tunnel Warfare HDU - 1540(线段树最长连续区间)

    题意: 一条线上的点,D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点.   解析: 线段树结点 设置一个  lq记录区间左端点开始的最大连续个数,  rq ...

随机推荐

  1. 如何下载 Ubuntu 镜像文件?

    Ubuntu,是一款基于 Debian Linux 的以桌面应用为主的操作系统,内容涵盖文字处理.电子邮件.软件开发工具和 Web 服务等,可供用户免费下载.使用和分享. 但是对于国内的用户来说如果直 ...

  2. 计算机网络之ARP协议

    ARP ARP(Address Resolution Protocol),即地址解析协议,是根据IP地址解析物理地址的一个TCP/IP协议.主机将包含目标IP地址信息的ARP请求广播到网络中的所有主机 ...

  3. vue的生命函数周期以及钩子函数的详解

      首先我们先附上官网的图 图中展现出的是vue整个生命周期以及钩子函数 1- beforeCreate(创建前) 2- created(创建完成) 3- beforeMount(挂载前) 4- mo ...

  4. 《UNIX环境高级编程》(APUE) 笔记第十章 - 信号

    10 - 信号 GitHub 地址 1. 信号 信号是 软中断 ,信号提供了一种处理异步事件的方法. 当造成信号的事件发生时,为进程 产生 一个信号(或向进程 发送 一个信号).事件 可以是硬件异常( ...

  5. 一.1搭建跨平台的统一python开发环境

    搭建跨平台的统一python开发环境: 使用开发环境的好处: 可不用在服务器上直接修改源代码---写的代码首先得入版本库(放git或giitlab中),在本地写代码提交到git中.然后在服务器上git ...

  6. UID,GID,口令

    摘自:http://cn.linux.vbird.org/linux_basic/0410accountmanager_1.php (完)

  7. Repeater 横向显示数据

    <asp:Repeater ID="Repeater1" runat="server"> <ItemTemplate> <ul s ...

  8. 【Oracle】rman中SBT_TYPE类型的备份如何删除

    技阳的rman数据库出现删除rman备份失败,原因是出现SBT_TYPE的磁带备份. [BEGIN] 2018/8/13 13:48:42 RMAN> list backup; List of ...

  9. java 中Object类中toString()的使用

    1. 当我们输出一个对象的引用时,实际上就是调用当前对象的toString() 2. Object类中toString()的定义: public String toString() { return ...

  10. HDU 5963 朋友 (找规律,思维)

    HDU 5963 朋友 题目大意 B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点 ...