HDU 1540<线段树,区间并>
题意:
维护各个点的连续的最大连续长度。
思路:
主要是维护一个区间的三个变量ll,f[i].l为起点向右的最大连续
长度,rl:f[i].r为起点向左的最大连续长度,ml:[l,r]区间内的
最大连续长度,便于合并。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100000+100;
struct node
{
int l,r;
int ll,rl,ml;
};
int a[maxn];
int sti[maxn];//sickc,数组的话更快,也更方便
int top=0;
node f[maxn*4];
void maketree(int i,int l,int r)
{
f[i].l=l;
f[i].r=r;
f[i].ll=f[i].rl=f[i].ml=r-l+1;//刚开始都连续
if(l==r)
return ;
int mid=(l+r)>>1;
maketree(i<<1, l, mid);
maketree(i<<1|1, mid+1, r);
}
void update(int i,int x,int v)
{
if(f[i].l==f[i].r)//叶子结点
{
f[i].ll=f[i].rl=f[i].ml=v;//v=0||1;
return ;
}
int mid=(f[i].l+f[i].r)>>1;
if(x<=mid) update(i<<1, x, v);
else update(i<<1|1, x, v);
//合并操作:!
//ml
f[i].ml=max(f[i<<1].ml,f[i<<1|1].ml);
f[i].ml=max(f[i].ml,f[i<<1].rl+f[i<<1|1].ll);
//ll
f[i].ll=f[i<<1].ll;
if(f[i].ll==f[i<<1].r-f[i<<1].l+1)
f[i].ll+=f[i<<1|1].ll;
//rl
f[i].rl=f[i<<1|1].rl;
if(f[i].rl==f[i<<1|1].r-f[i<<1|1].l+1)
f[i].rl+=f[i<<1].rl;
}
int query(int i,int x)//寻找连续区间的最大值
{
if(f[i].l==f[i].r||f[i].ml==f[i].r-f[i].l+1||f[i].ml==0)
//是叶子节点||都连续||都不连续直接返回ml
return f[i].ml;
int mid=(f[i].l+f[i].r)>>1;
if(x<=mid){
if(x>=mid-f[i<<1].rl+1)//主要看代码
return query(i<<1, x)+query(i<<1|1, mid+1);
else
return query(i<<1, x);
}
else {
if(x<=mid+f[i<<1|1].ll)
return query(i<<1, mid)+query(i<<1|1, x);
else
return query(i<<1|1, x);
}
}
int main ()
{
int n,m;
char s[5];
while(~scanf("%d%d",&n,&m))//WA一次
{
top=0;
maketree(1, 1, n);
for(int i=1;i<=m;i++)
{
scanf("%s",s);
if(s[0]!='R'){
int t;
scanf("%d",&t);
if(s[0]=='D'){
sti[++top]=t;
update(1, t, 0);
}
else if(s[0]=='Q')
printf("%d\n",query(1, t));
}
else
update(1, sti[top--], 1);
}
}
return 0;
}
HDU 1540<线段树,区间并>的更多相关文章
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
- HDU 1698 线段树 区间更新求和
一开始这条链子全都是1 #include<stdio.h> #include<string.h> #include<algorithm> #include<m ...
- HDU - 1540 线段树的合并
这个题题意我大概解释一下,就是一开始一条直线,上面的点全是联通的,有三种操作 1.操作D把从左往右第x个村庄摧毁,然后断开两边的联通. 2.询问Q节点相联通的最长长度 3.把最后破坏的村庄重建. 这个 ...
- E - Just a Hook HDU - 1698 线段树区间修改区间和模版题
题意 给出一段初始化全为1的区间 后面可以一段一段更改成 1 或 2 或3 问最后整段区间的和是多少 思路:标准线段树区间和模版题 #include<cstdio> #include& ...
- hdu 1698 线段树 区间更新 区间求和
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 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 ...
- HDU - 1698 线段树区间修改,区间查询
这就是很简单的基本的线段树的基本操作,区间修改,区间查询,对区间内部信息打上laze标记,然后维护即可. 我自己做的时候太傻逼了...把区间修改写错了,对给定区间进行修改的时候,mid取的是节点的左右 ...
- HDU 5023线段树区间染色,统计区间内颜色个数
这个也是一个线段树的模板 #include<iostream> #include<string.h> #include<algorithm> #include< ...
- hdu 1540 线段树
这题的意思是现在有一些村庄成一条直线排列,现在有三个操作,D:摧毁一个指定的村庄,Q:询问与指定村庄相连的村庄个数, 就是这个村庄向左和向右数村庄数量,遇到尽头或损坏的村庄为止,这个就是与这个村庄相连 ...
随机推荐
- 各硬件设备在Linux中的文件名
- Spring入门学习(二)三种实例化bean的方法
前面的哪一种就是通过构造函数来实例化对象 下面我们可能用到工厂方法来视力话对象,这样我们的配置文件又该怎么配置呢 <bean name="service2" class=&q ...
- zookeeper(1)
参考文档:zookeeper中文网 一.介绍安装 zookeeper 是一个高效的分布式协调服务,它暴露了一些公用服务,比如命名/配置/同步控制/群组服务等.我们可以使用ZK来实现一些功能,例如:达成 ...
- lnmp vps服务器删除mysql日志文件三种方法
我在上一篇文章介绍了著名的LNMP主机一键安装工具,对比了军哥lnmp和AMH主机的差别,由于AMH拥有用户后台界面,易于新手操作,值得推荐. 但是,上周末我网站宕机,收到DNSPOD发来了宕机提醒, ...
- Gentoo安装详解(四)-- 声卡设置
硬件检测 To choose the right driver, first detect the used audio controller. You can use lspci for this ...
- VMware 下的Linux系统远程连接putty
ifconfig查看ip地址 虚拟网卡需要自己新建 nat8 putty不能显示中文的解决办法 http://jingyan.baidu.com/article/5552ef47df8a97518f ...
- 值得一提:关于 HDFS 的 file size 和 block size
转 http://blog.csdn.net/samhacker/article/details/23089157?utm_source=tuicool&utm_medium=referral ...
- perl Socket接收超时设置
一般来说, IO::Socket::INET里的Timeout设置是对于conncet的 如果你想设置recv接收超时, 可以这样设置: usr Socket: ...... , )); #注意这里p ...
- ios实现文字的自适应
如果你是用xib搭的cell界面 那么cell上面的UIlabel就不能设置宽高 要选择上下左右自适应 并且label的行数设置为0 然后在tableView的代理方法 (UITable ...
- 常用CSS样式 持续更新
+ CSS + a标签 - 去除a标签下划线 a{ text-decoration:none; } - 未被访问状态下的a标签去除下划线 a:link{ text-decoration:none; } ...