/*
hdu-1540 题意:一个线段,长度为n,三种操作,Dx,挖掉某个点;R,恢复最近被挖掉的点;Qx查询该点所在的连续区间的长度;
树的节点维护三个变量,该节点左边界开始连续的个数ll,右边界开始向左连续的个数rl,(在该区间内),该区间内最大的连续区间的长度ml;
最后一个变量是为了方便判断,主要的还是前两个;
修改的时候先是深入单点修改单点信息,然后回溯上来更父结点,更新的时候有点复杂;
查询的时候借助ml的长度减少计算量,快速返回;
区间合并;
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
struct Node
{
int l,r,ll,rl,ml;
}tr[];
void build(int rt,int l,int r)
{
tr[rt].l=l;
tr[rt].r=r;
tr[rt].ll=tr[rt].rl=tr[rt].ml=r-l+;
if(l==r)
return ;
int mid=(l+r)/;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
}
void Update(int rt,int l,int r,int t,int val)//t是要改的点;
{
if(l==r) //找到单点;
{
if(val==)
{
tr[rt].ll=tr[rt].rl=tr[rt].ml=;//改单点的信息;
}
else
{
tr[rt].ll=tr[rt].rl=tr[rt].ml=;
}
return ;
}
int mid=(l+r)/;//二分查找区间;
if(t<=mid)
{
Update(rt<<,l,mid,t,val);
}
else
{
Update(rt<<|,mid+,r,t,val);
}
// pushup操作;
tr[rt].ll=tr[rt<<].ll; //左子树的左侧边界的值给父节点;
tr[rt].rl=tr[rt<<|].rl; //右子树的有边界的值给父结点;
tr[rt].ml=max(tr[rt<<].ml,tr[rt<<|].ml); //左右子树的最大连续数;
tr[rt].ml=max(tr[rt].ml,tr[rt<<].rl+tr[rt<<|].ll); //两个子树的交接处的最大连续数;
if(tr[rt<<].ll==mid-l+)
tr[rt].ll+=tr[rt<<|].ll; //如果左子树是全连续的,就更新父节点的左边界最大连续数;
if(tr[rt<<|].rl==r-mid) //如果右子树是连续的,就更新父结点的有边界的最大连续数;
tr[rt].rl+=tr[rt<<].rl;
}
int Query(int rt,int l,int r,int t)//查询与这个点连接的最长序列;
{
if(l==r||tr[rt].ml==||tr[rt].ml==r-l+) //如果找到单点,或该区间全空,或该区间全满;就返回;
return tr[rt].ml;
int mid=(l+r)/;
if(t<=mid) //如果该点在左子树上
{
if(t>=tr[rt<<].r-tr[rt<<].rl+) //如果该点是在左子树右边界点连续范围,就进入左子树继续搜索该点并加上搜索右子树的左边界那个点的结果;
return Query(rt<<,l,mid,t)+Query((rt<<)|,mid+,r,mid+);
else
return Query(rt<<,l,mid,t); //如果不再右连续块内就进左子树继续搜索;
}
else//右子树;
{
if(t<=tr[rt<<|].l+tr[rt<<|].ll-) //在右子树的左侧连续的部分内,就加上左子树上的数据,左子树右边界的(不能用有子树的数据因为那不是全部的数据);
return Query(rt<<|,mid+,r,t)+Query(rt<<,l,mid,mid);
else
return Query(rt<<|,mid+,r,t);
}
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF&&n&&m)
{
memset(tr,,sizeof(tr));
stack<int > z;
build(,,n);
for(int i=;i<m;i++)
{
char a[];
scanf("%s",a);
if(a[]=='D')
{
int x;
scanf("%d",&x);
z.push(x);
Update(,,n,x,); //0代表删除操作;
}
else if(a[]=='R')
{
if(!z.empty())
{
int x=z.top();
z.pop();
Update(,,n,x,); //1代表回复操作;
}
}
else if(a[]=='Q')
{
int x;
scanf("%d",&x);
int ans=Query(,,n,x);
printf("%d\n",ans);
}
}
}
return ;
}

kb-09-线段树--区间合并比较繁的更多相关文章

  1. HYSBZ 1858 线段树 区间合并

    //Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...

  2. poj3667 线段树 区间合并

    //Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

  3. POJ 3667 Hotel(线段树 区间合并)

    Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...

  4. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

  5. HDU 3911 Black And White(线段树区间合并+lazy操作)

    开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...

  6. hdu3911 线段树 区间合并

    //Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

  7. 线段树(区间合并) POJ 3667 Hotel

    题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...

  8. HDU 3308 LCIS (线段树区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...

  9. SPOJ GSS1_Can you answer these queries I(线段树区间合并)

    SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...

  10. 树链剖分——线段树区间合并bzoj染色

    线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了.. 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 struct Seg ...

随机推荐

  1. 在一个另一个文件中 #include一个**dlg.h文件,会发生dlg的资源ID未定义的错误 :

    1    在一个另一个文件中 #include一个**dlg.h文件,会发生dlg的资源ID未定义的错误 : dlg1.h(23) : error C2065: 'IDD_DIALOG1' : und ...

  2. jQuery如何获取选中单选按钮radio的值

    使用jquery获取radio的值,最重要的是掌握jquery选择器的使用,在一个表单中我们通常是要获取被选中的那个radio项的值,所以要加checked来筛选,比如有以下的一些radio项: 1. ...

  3. centos7-httpd服务器

    Apache WEB服务器入门简介: Apache HTTP Server是Apache软件基金会的一个开源的网页服务器,可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是目 ...

  4. 【原】基于matlab的蓝色车牌定位与识别---绪论

    本着对车牌比较感兴趣,自己在课余时间摸索关于车牌的定位与识别,现将自己所做的一些内容整理下,也方便和大家交流. 考虑到车牌的定位涉及到许多外界的因素,因此有必要对车牌照的获取条件进行一些限定: 一.大 ...

  5. Java JDBC的基本知识

    CallableStatement接口——主要调用数据库中的存储过程 即为一种方法,可以调用, 传递参数   delimiter // //这里是改变执行操作语句的分隔符,也就是将SQL语句的&quo ...

  6. 封装一个优雅的element ui表格组件

    现在做后台系统用vue + elementUI 的越来越多,那element ui的 el-table 组件肯定也离不开.虽然element ui的table组件很好.但是表格和分页是分离的.每次写表 ...

  7. Vue表单输入绑定

    <h3>基础用法</h3> <p>你可以用<strong>v-model</strong>指令在表单input,textarea以及sele ...

  8. STA basic

  9. 【linux】 服务器文件说明

    文件名 说明 /etc/resolv.conf  域名解析服务器地址文件 /etc/services 服务程序对应端口号文件 /etc/passwd 登录账号文件 /etc/hosts 本地IP域名解 ...

  10. numpy 三个点的使用[...]

    numpy [...]语法简单使用 Python numpy中切片功能与列表切片类似,但功能更加强大 本文主讲numpy中[...]的简单使用,后续工作继续补充. import numpy >& ...