线段树(区间合并)HDU - 1540
题意:输入n,m,给定n个相互连通的村庄,有m个操作,D x,表示破坏x村庄使其与相邻的两个村庄不相通,R 表示修复上一个被破坏的村庄,与相邻的两个村庄联通。Q x表示与x相连的村庄有多少个。
思路:一开始只知道是线段树,想着肯定得用结构体记录每个点的信息,怎么记录就不知道了。然后学了线段树区间合并。
首先要知道结构体记录的信息,当前区间 的左右边界、 左右边最大连续区间、总的最大连续区间 、长度。
那么对于初始化就知道了。
然后看pushdown函数,直到左右儿子信息要更新父节点的信息(详细看注释)
线段树的更新就是单点修改,当找到要更新的节点时,就要更新这个节点的信息了。同时利用回溯pushdown。
单点查询:如果能找到那个点,就返回最大连续区间长度,对于查询写了个式子,模模糊糊有点理解:(也就是说,如果处在左儿子的右边最大区间,该 右边最大区间 和 右儿子最大连续左区间一定相连 (这是性质),加上即可
#include<stdio.h>
#include<stack>
#include<string.h>
using namespace std;
struct node
{
int l,r,ls,rs,sum,len;
}ans[200010];/*记录 左端最大连续区间 右端最大连续区间 最大连续区间*/
void pushdown(int o)
{
ans[o].ls=ans[o<<1].ls;
ans[o].rs=ans[o<<1|1].rs;
ans[o].sum=max(ans[o<<1|1].sum,ans[o<<1].sum);
if(ans[o<<1].ls==ans[o<<1].len)/*如果左儿子区间全都相连*/
ans[o].ls+=ans[o<<1|1].ls;/*加上右儿子的左区间*/
if(ans[o<<1|1].rs==ans[o<<1|1].len)/*同理*/
ans[o].rs+=ans[o<<1].rs;
}
void build(int l,int r,int o)/*初始化*/
{
ans[o].l=l,ans[o].r=r;
ans[o].len=(r-l+1);
ans[o].ls=ans[o].rs=ans[o].sum=1;/*r-l+1*/
if(l==r)
return;
int mid=(l+r)>>1;
build(l,mid,o<<1);
build(mid+1,r,o<<1|1);
pushdown(o);
return ;
}
void update(int o,int x,int judge)/*单点修改*/
{
if(ans[o].l==ans[o].r)
{
ans[o].sum=ans[o].ls=ans[o].rs=judge;
return ;
}
int mid=(ans[o].l+ans[o].r)>>1;
if(x<=mid) update(o<<1,x,judge);
else update(o<<1|1,x,judge);
pushdown(o);
}
int query(int o,int x)
{
if(ans[o].l==ans[o].r)
{
return ans[o].sum;/* 0 或 1*/
}
int mid=(ans[o].l+ans[o].r)>>1;
// printf("%d %d\n",x,mid);/*相邻节点之间区间是连续的*/
if(x<=mid)
{
/*满足这个条件好像是相连的 l+ls = r - rs +1 ,rs与ls相连 x正好是临界点 */
if(x>=ans[o<<1].r-ans[o<<1].rs+1)/*判断x点在左儿子的左右区间*/
return ans[o<<1].rs+ans[o<<1|1].ls;/*为什么相加??*/
else
return query(o<<1,x);
}
else
{
if(ans[o<<1|1].ls+ans[o<<1|1].l-1>=x)
return ans[o<<1|1].ls+ans[o<<1].rs;
else
return query(o<<1|1,x);
}
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
build(1,n,1);
char a[10];
int x;
stack<int>s;
for(int i=1;i<=m;i++)
{
scanf("%s",a);
if(a[0]=='D')
{
scanf("%d",&x);
s.push(x);
update(1,x,0);
}
else if(a[0]=='Q')
{
scanf("%d",&x);
printf("%d\n",query(1,x));
}
else if(a[0]=='R')
{
x=s.top();
s.pop();
update(1,x,1);
}
}
}
return 0;
}
)
线段树(区间合并)HDU - 1540的更多相关文章
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
- hdu 3911 Black And White (线段树 区间合并)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3911 题意: 给你一段01序列,有两个操作: 1.区间异或,2.询问区间最长的连续的1得长度 思路: ...
- HDU 3308 (线段树区间合并)
http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作 : 1 修改 单点 a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...
- HDU 6638 - Snowy Smile 线段树区间合并+暴力枚举
HDU 6638 - Snowy Smile 题意 给你\(n\)个点的坐标\((x,\ y)\)和对应的权值\(w\),让你找到一个矩形,使这个矩阵里面点的权值总和最大. 思路 先离散化纵坐标\(y ...
- LCIS HDU - 3308 (线段树区间合并)
LCIS HDU - 3308 Given n integers. You have two operations: U A B: replace the Ath number by B. (inde ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
- hdu 3308(线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- HDU 3911 线段树区间合并
北京赛区快了,准备袭击数据结构和图论.倒计时 18天,线段树区间合并.维护一个最长连续.. 题意:给一个01串,以下有一些操作,问区间最长的连续的1的个数 思路:非常裸的线段树区间合并 #includ ...
- Tunnel Warfare(HDU1540+线段树+区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540 题目: 题意:总共有n个村庄,有q次操作,每次操作分为摧毁一座村庄,修复一座村庄,和查询与询问的 ...
随机推荐
- C++走向远洋——28(项目三,时间类,2)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:time.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- webpack环境配置2
1.webpack安装 Step 1: 首先安装Node.js, 在1中已经详细介绍了. Step2: 在Git或者cmd中输入下面这段代码, 通过全局先将webpack指令安装进电脑中npm ins ...
- Pom.xml的依赖自动生成
1.第一种用引入jar包的方法 网盘链接:https://pan.baidu.com/s/10HNjNeZc1d5QrFNtvLPWBA 提取码:oako 以上是整个文件直接用idea打开即可 imp ...
- Ribbon进行服务调用/负载均衡以及请求重试配置
Ribbon负载均衡 经过对Eureka的认识,及Eureka集群的搭建,已经基本可以入门Eureka的使用.之前对于服务调用者我们是直接获取注册列表后通过 get(0) 的方式来获取第一个注册信息. ...
- RTMP协议推流交互流程
目录 RTMP协议推流交互流程 RTMP协议推流流程 RTMP握手 RTMP建立连接 RTMP建流&Play Wireshark抓个RTMP流 RTMP协议推流交互流程 想了解下直播常见协议R ...
- vue——一个页面实现音乐播放器
请忽略下面这段文字年关将至,时间好歹又多出了些许.却不敢过度消遣.岁月未曾饶过我,我亦不想饶过岁月.且将它塞得膨胀,让这一年看似加更充实.不曾料想我一个爱些风花雪月.研墨行歌之人,却做起了碼农这一行当 ...
- scroll-view组件bindscroll实例应用:自定义滚动条
我们知道scroll-view组件作为滑动控件非常好用,而有时候我们想放置一个跟随滚动位置来跟进的滚动条,但又不想用滚动条api该怎么办呢?(当然是自己写一个呗还能怎么办[自黑冷漠脸])嗯,没错.自己 ...
- 深入学习JAVA注解-Annotation(学习过程)
JAVA注解-Annotation学习 本文目的:项目开发过程中遇到自定义注解,想要弄清楚其原理,但是自己的基础知识不足以支撑自己去探索此问题,所以先记录问题,然后补充基础知识,然后解决其问题.记录此 ...
- 2020ubuntu1804server编译安装redis笔记(一)及报make test错误解决办法
redis的大名我想大家都不陌生,今天在ubuntu server上进行编译安装,虽然apt也可以安装,但作为内存数据库,redis又是c开发的,编译安装,对机器的适应和性能更好. 安装笔记如下 第1 ...
- JavaFX之FXML+CSS创建窗体以及透明窗体添加阴影
前言 开通博客园有一段日子了,一直没空也没想好该写点什么.最近正好在做一个桌面程序,初次接触JavaFX,体验下来确实比swing好用不少.索性便记记学习笔记吧,虽然FX好像挺没存在感,没人用的感觉. ...