参考:https://blog.csdn.net/u010336344/article/details/53034372

神一样的线段树

线段树上维护:ll从左开始最长空段;rr从右开始最长空段;len区间中最长空段;tg:-1不全是空的,0区间内全是空的,1区间内全是满的;lz下传标记:-1没标记,1下传满的,0下传空的

修改的时候,修改到一整个区间,就把lz和tg改了,ll、rr、len全改成r-l+1或者0

然后下传标记的时候同上

向上合并的时候,先把左右区间的ll、rr穿给当前区间,然后根据左右区间的tg是否为0(全空)来扩大当前区间的ll、rr;tg根据左右区间tg更改;len从左区间len、右区间len和左区间rl+右区间ll中取max

查询的时候优先查左边即可,像二分一样在树上跳

#include<iostream>
#include<cstdio>
using namespace std;
const int N=100005;
int n,m;
struct xds
{
int l,r,ll,rl,tg,len,lz;
}t[N<<1];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void pd(int ro)
{
if(t[ro].lz!=-1)
{
if(t[ro].lz==1)
{
t[ro<<1].rl=t[ro<<1].ll=t[ro<<1].len=0;
t[ro<<1|1].rl=t[ro<<1|1].ll=t[ro<<1|1].len=0;
}
else
{
t[ro<<1].rl=t[ro<<1].ll=t[ro<<1].len=t[ro<<1].r-t[ro<<1].l+1;
t[ro<<1|1].rl=t[ro<<1|1].ll=t[ro<<1|1].len=t[ro<<1|1].r-t[ro<<1|1].l+1;
}
t[ro<<1].tg=t[ro<<1|1].tg=t[ro].tg;
t[ro<<1].lz=t[ro<<1|1].lz=t[ro].lz;
t[ro].lz=-1;
}
}
void ud(int ro)
{
if(t[ro<<1].tg==t[ro<<1|1].tg)
t[ro].tg=t[ro<<1].tg;
else
t[ro].tg=-1;
t[ro].ll=t[ro<<1].ll;
t[ro].rl=t[ro<<1|1].rl;
if(!t[ro<<1].tg)
t[ro].ll+=t[ro<<1|1].ll;
if(!t[ro<<1|1].tg)
t[ro].rl+=t[ro<<1].rl;
t[ro].len=max(max(t[ro<<1].len,t[ro<<1|1].len),t[ro<<1].rl+t[ro<<1|1].ll);
}
void build(int ro,int l,int r)
{
t[ro].l=l,t[ro].r=r,t[ro].len=t[ro].ll=t[ro].rl=r-l+1,t[ro].lz=-1;
if(l==r)
return;
int mid=(l+r)>>1;
build(ro<<1,l,mid);
build(ro<<1|1,mid+1,r);
}
void update(int ro,int l,int r,int k)
{
if(t[ro].l==l&&t[ro].r==r)
{
if(k)
t[ro].rl=t[ro].ll=t[ro].len=0;
else
t[ro].rl=t[ro].ll=t[ro].len=r-l+1;
t[ro].tg=t[ro].lz=k;
return;
}
pd(ro);
int mid=(t[ro].l+t[ro].r)>>1;
if(r<=mid)
update(ro<<1,l,r,k);
else if(l>mid)
update(ro<<1|1,l,r,k);
else
update(ro<<1,l,mid,k),update(ro<<1|1,mid+1,r,k);
ud(ro);
}
int ques(int ro,int k)
{
int re=-1;
while(t[ro].l&&t[ro].len>=k)
{
if(t[ro].ll>=k)
{
re=t[ro].l;
break;
}
if(t[ro<<1].len>=k)
ro<<=1;
else
{
if(t[ro<<1].rl!=0&&t[ro<<1].rl+t[ro<<1|1].ll>=k)
{
re=t[ro<<1].r-t[ro<<1].rl+1;
break;
}
else
ro=ro<<1|1;
}
}
return re;
}
int main()
{
n=read(),m=read();
build(1,1,n);
while(m--)
{
int o=read();
if(o==1)
{
int x=read(),now=ques(1,x);
if(now!=-1)
{
printf("%d\n",now);
update(1,now,now+x-1,1);
}
else
puts("0");
}
else
{
int x=read(),y=read();
update(1,x,x+y-1,0);
}
}
return 0;
}

bzoj 1593: [Usaco2008 Feb]Hotel 旅馆【线段树】的更多相关文章

  1. BZOJ 1593: [Usaco2008 Feb]Hotel 旅馆 [线段树]

    传送门 题意: 操作1:找长为$len$的空区间并填满,没有输出$0$ 操作2:将$[l,r]$之间的区间置空 我真是太弱了这种线段树还写了一个半小时,中间为了查错手动模拟了$30min$线段树操作, ...

  2. bzoj1593 [Usaco2008 Feb]Hotel 旅馆(线段树)

    1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 758  Solved: 419[Submit ...

  3. 【bzoj1593】[Usaco2008 Feb]Hotel 旅馆 线段树区间合并

    题目描述 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 <= N & ...

  4. BZOJ 1593: [Usaco2008 Feb]Hotel 旅馆

    Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N (1 &l ...

  5. 1593: [Usaco2008 Feb]Hotel 旅馆

    1593: [Usaco2008 Feb]Hotel 旅馆 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 391  Solved: 228[Submit ...

  6. 【BZOJ】1593: [Usaco2008 Feb]Hotel 旅馆

    [算法]线段树(经典线段树上二分) [题意]n个房间,m个询问,每次订最前的连续x个的空房间,或退订从x开始y个房间,求每次订的最左房间号. [题解]关键在于找连续x个空房间,经典二分. 线段树标记s ...

  7. 线段树||BZOJ1593: [Usaco2008 Feb]Hotel 旅馆||Luogu P2894 [USACO08FEB]酒店Hotel

    题面:P2894 [USACO08FEB]酒店Hotel 题解:和基础的线段树操作差别不是很大,就是在传统的线段树基础上多维护一段区间最长的合法前驱(h_),最长合法后驱(t_),一段中最长的合法区间 ...

  8. 【最长连续零 线段树】bzoj1593: [Usaco2008 Feb]Hotel 旅馆

    最长连续零的线段树解法 Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负 责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大 ...

  9. BZOJ1593 [Usaco2008 Feb]Hotel 旅馆

    裸上线段树,就是记的东西有点多... 每个点记区间左端最长0,右端最长0,中间最长0,和tag表示是否全为0/1 直接更新就好,查询的时候先查左儿子,然后查中间,最后查右儿子... /******** ...

随机推荐

  1. Quartz.Net 学习之路01 安装Quartz.Net

    Quartz.Net 系列文章的第一篇,至于Quartz.Net 是做什么的我就不介绍了,相信要用到它的都知道它是用来干嘛的: Quartz.Net安装方法: 1.打开项目,在VS“工具”菜单选中“库 ...

  2. C51 keil 注意事项

    下载程序需要生成hex文件 仿真 蜂鸣器 音调:频率 音量:高低电平占空比 有源:上面没有加号,只需高低电平即可发声 无源:上面有加号,不仅要电平,还要, 的频率

  3. Codeforces Round #355 (Div. 2)-B. Vanya and Food Processor,纯考思路~~

    B. Vanya and Food Processor time limit per test 1 second memory limit per test 256 megabytes input s ...

  4. noip模拟赛 集合

    分析:感觉像是贪心,再看数据范围这么大,肯定是贪心没错.但是要怎么贪呢?主要的思想是让每次往上加的数尽量多,肯定要先把0分裂,如果能正好一起跳到最终状态就好.举个例子:5,3,2,1,最大值比次大值大 ...

  5. codeforces 361A

    //这题看着吓人,为何这么水 #include<stdio.h> int main() {  int n,m,i,j;  while(scanf("%d%d",& ...

  6. node的express框架,核心第三方模块body-parser 获取我们所有post请求传过来数据

    - 安装 body-parser模块- npm install body-parser -S - 调用- let bodyParser=require('body-parser'); - 设置中间件- ...

  7. UEFI 下安装 ubuntu 及 win8 双系统 的一些事

    给电脑原装的win8系统装Ubuntu 出现了好多问题,重装多次,刷坏一块主板后,(都是泪啊...) 终于成功. 可能的问题 1:win8 系统下进入 blos 解决方案  1)关闭快速启动:管理员命 ...

  8. linux下crontab安装和使用(定时任务)

    在Unix和Linux的操作系统之中,cron可以让系统在指定的时间,去执行某个指定的任务,crontab命令常用于管理对应的cron. 一.crontab在线安装 yum -y install vi ...

  9. Sockets Tutorial

    Sockets Tutorial This is a simple tutorial on using sockets for interprocess communication. The clie ...

  10. hdu 5253 连接的管道(kruskal)(2015年百度之星程序设计大赛 - 初赛(2))

    连接的管道 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...