/*
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. 通过WMIC导出系统日志

    查看日志类型 wmic nteventlog get filename C:\>wmic nteventlog get filename FileName appevent secevent s ...

  2. uoj#300.【CTSC2017】吉夫特

    题面:http://uoj.ac/problem/300 一道大水题,然而我并不知道$lucas$定理的推论.. $\binom{n}{m}$为奇数的充要条件是$n&m=n$.那么我们对于每个 ...

  3. javaweb基础(3)_tomcat下部署项目

    一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命令的用法如下:

  4. A. Vitya in the Countryside

    A. Vitya in the Countryside time limit per test 1 second memory limit per test 256 megabytes input s ...

  5. 在Keras中导入测试数据的方法

    https://blog.csdn.net/ethantequila/article/details/80322425?utm_source=blogxgwz2

  6. [LUOGU] P2634 [国家集训队]聪聪可可

    点分治裸题,甚至不需要栈回撤. 尝试用容斥写了一波,就是把所有子树混一块计算,最后减去子树内路径条数. #include<iostream> #include<cstring> ...

  7. Python中的字典与集合

    今天我们来讲一讲python中的字典与集合 Dictionary:字典 Set:集合 字典的语法: Dictionary字典(键值对) 语法: dictionary = {key:value,key: ...

  8. 牛客练习赛29 B

    炎热的早上,gal男神们被迫再操场上列队,gal男神们本来想排列成x∗x的正方形,可是因为操场太小了(也可能是gal男神太大了),校长安排gal男神们站成多个4∗4的正方形(gal男神们可以正好分成n ...

  9. Markdown 使用锚点

    首先是建立一个跳转的连接: [说明文字](#jump) 然后标记要跳转到什么位置即可: <span id = "jump">跳转到这里:</span>

  10. BZOJ 5299: [Cqoi2018]解锁屏幕

    状压DP #include<cstdio> using namespace std; const int mod=1e8+7; int F[1000005][25],dis[25][25] ...