kb-09-线段树--区间合并比较繁
/*
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-线段树--区间合并比较繁的更多相关文章
- HYSBZ 1858 线段树 区间合并
//Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...
- poj3667 线段树 区间合并
//Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- POJ 3667 Hotel(线段树 区间合并)
Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
- hdu3911 线段树 区间合并
//Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- 线段树(区间合并) POJ 3667 Hotel
题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
- SPOJ GSS1_Can you answer these queries I(线段树区间合并)
SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...
- 树链剖分——线段树区间合并bzoj染色
线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了.. 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 struct Seg ...
随机推荐
- React组件间通信
众所周知,ReactJS组件与组件之间的通信是一个难点.在React实际开发中,父子组件之间的传值是比较常见的,刚入门的小伙伴很容易被组件之间的通信绕懵. 今天花了点时间总结了一下React父子组件之 ...
- FTP服务器建立windows与Linux的文件共享与读写操作
centos7搭建vsftpd 2018-11-15 我们有时想要windows与Linux互传文件,就要用到vsftpd了.它仅仅在windows上面操作,就可以实现与Linux的通信,详情如下: ...
- Bootstrap 徽章(Badges)
本章将讲解Bootstrap徽章(Badges),徽章与标签相似,主要的区别是徽章的圆角比较圆滑. 徽章(Badges)主要用于突出显示新的或未读的项,如果使用徽章,只需要把<span clas ...
- iOS小技巧–用runtime 解决UIButton 重复点击问题
什么是这个问题 我们的按钮是点击一次响应一次, 即使频繁的点击也不会出问题, 可是某些场景下还偏偏就是会出问题. 通常是如何解决 我们通常会在按钮点击的时候设置这个按钮不可点击. 等待0.xS的延时后 ...
- 【线段树 树链剖分 差分 经典技巧】loj#3046. 「ZJOI2019」语言【未完】
还是来致敬一下那过往吧 题目分析 先丢代码 #include<bits/stdc++.h> ; ; ; struct node { int top,son,fa,tot; }a[maxn] ...
- 【贪心】bzoj1577: [Usaco2009 Feb]庙会捷运Fair Shuttle
一类经典的线段贪心 Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i ...
- pandas交叉表和透视表及案例分析
一.交叉表: 作用: 交叉表是一种用于计算分组频率的特殊透视图,对数据进行汇总 考察预测数据和正式数据的对比情况,一个作为行,一个作为列 案例: 医院预测病人病情: 真实病情如下数组(B:有病,M:没 ...
- mysql 5.7安装密码校验插件validate_password
在使用服务器插件之前,必须将它们加载到服务器中.MySQL支持在服务器启动和运行时加载插件.还可以在启动时控制加载插件的激活状态,并在运行时卸载它们.在加载插件时,可以从INFORMATION_SCH ...
- css3属性:美化表单、点击元素产生的背景与边框怎么去掉,滚动回弹效果
- 22.Yii2.0框架多表关联一对一查询之hasOne
思路: 通过文章查它对应的分类信息 一对一的关系 控制器里 //一对一关联查询 public function actionRelatesone() { //方法一,hasOne() 用查一条文章的结 ...