嘟嘟嘟

这道题以前在学校内网刷过类似的,AC了后还挺有成就感,所以更详细的题解请看这里

总的来说,就是用线段树维护区间最长连续0.因此我们要维护这么几个值:lmax:从当前区间左端点开始最长的连续0的长度;rmax:右端点开始最长连续0的长度;imax当前区间最长连续0的长度。有了这三个量,区间就可以合并了。

合并的方法看上面的链接,这里不再细讲了,这道题主要的区别查询。

查询是找长度为x的区间的位置,而不是在给定区间中查询最长连续区间。查询的具体步骤是这样的:

1.当前区间连续的最长长度比要找的len小,自然返回0。

2.否则我们看lmax[now],这个区间左起最长长度,如果大于len,就返回左端点就行啦。

3.因为题中说要使房间号尽量小,所以接下来应该看rmax[now << 1] + lmax[now << 1 |1]和len的关系,如果包含len,就返回r[now << 1] - rmax[now << 1] + 1.

4.最后就只能递归找右子区间了。

就因为上面的逻辑我刚开始想的不对,于是debug了快一个下午……

emacs格式,代码缩进很丑

 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 5e4 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), las = ' ';
while(!isdigit(ch)) las = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << ) + (ans << ) + ch - '', ch = getchar();
if(las == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar(x % + '');
} int n, m; struct Tree
{
int l, r, lzy;
int lmax, rmax, imax;
Tree operator + (const Tree& other)const
{
Tree ret;
ret.l = l; ret.r = other.r;
ret.lzy = -;
ret.lmax = lmax;
if(lmax == r - l + ) ret.lmax += other.lmax;
ret.rmax = other.rmax;
if(other.rmax == other.r - other.l + ) ret.rmax += rmax;
ret.imax = max(max(imax, other.imax), rmax + other.lmax);
return ret;
}
}t[maxn << ];
void build(int L, int R, int now)
{
t[now].l = L; t[now].r = R;
t[now].lzy = -;
t[now].lmax = t[now].rmax = t[now].imax = R - L + ;
if(L == R) return;
int mid = (L + R) >> ;
build(L, mid, now << );
build(mid + , R, now << | );
}
void pushdown(int now)
{
if(t[now].lzy != -)
{
t[now << ].lmax = t[now << ].rmax = t[now << ].imax = (t[now << ].r - t[now << ].l + ) * (t[now].lzy ^ );
t[now << | ].lmax = t[now << | ].rmax = t[now << | ].imax = (t[now << | ].r - t[now << | ].l + ) * (t[now].lzy ^ );
t[now << ].lzy = t[now << | ].lzy = t[now].lzy;
t[now].lzy = -;
}
}
void update(int L, int R, int now, int flg)
{
if(L == t[now].l && R == t[now].r)
{
t[now].lmax = t[now].rmax = t[now].imax = (R - L + ) * (flg ^ );
t[now].lzy = flg; return;
}
pushdown(now);
int mid = (t[now].l + t[now].r) >> ;
if(R <= mid) update(L, R, now << , flg);
else if(L > mid) update(L, R, now << | , flg);
else update(L, mid, now << , flg), update(mid + , R, now << | , flg);
t[now] = t[now << ] + t[now << | ];
}
int query(int len, int now)
{
if(t[now].imax < len) return ;
pushdown(now);
if(t[now].lmax >= len) return t[now].l;
else if(t[now << ].imax >= len) return query(len, now << );
else if(t[now << ].rmax + t[now << | ].lmax >= len) return t[now << ].r - t[now << ].rmax + ;
else return query(len, now << | );
} int main()
{
n = read(); m = read();
build(, n, );
for(int i = ; i <= m; ++i)
{
int d = read();
if(d == )
{
int x = read();
int ans = query(x, );
write(ans); enter;
if(ans) update(ans, ans + x - , , );
}
else
{
int L = read(), len = read();
update(L, L + len - , , );
}
}
return ;
}

[USACO08FEB]酒店Hotel的更多相关文章

  1. 洛谷P2894 [USACO08FEB]酒店Hotel

    P2894 [USACO08FEB]酒店Hotel https://www.luogu.org/problem/show?pid=2894 题目描述 The cows are journeying n ...

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

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

  3. P2894 [USACO08FEB]酒店Hotel

    P2894 [USACO08FEB]酒店Hotel 简单的线段树维护区间信息. 维护三个值,一个是从左端点能拓展的长度,一个是从右端点能脱产的的长度.另一个是整个区间内的最大连续零一长度. 记录这三个 ...

  4. 洛谷 P2894 [USACO08FEB]酒店Hotel 解题报告

    P2894 [USACO08FEB]酒店Hotel 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultur ...

  5. 线段树【洛谷P2894】 [USACO08FEB]酒店Hotel

    P2894 [USACO08FEB]酒店Hotel 参考样例,第一行输入n,m ,n代表有n个房间,编号为1---n,开始都为空房,m表示以下有m行操作,以下 每行先输入一个数 i ,表示一种操作: ...

  6. 浅谈线段树 (例题:[USACO08FEB]酒店Hotel)By cellur925

    今天我们说说线段树. 我个人还是非常欣赏这种数据结构的.(逃)因为它足够优美,有递归结构,有左子树和右子树,还有二分的思想. emm这个文章打算自用,就不写那些基本的操作了... 1° 简单的懒标记( ...

  7. [USACO08FEB]酒店Hotel 线段树

    [USACO08FEB]酒店Hotel 线段树 题面 其实就是区间多维护一个lmax,rmax(表示从左开始有连续lmax个空房,一直有连续rmax个空房到最右边),合并时讨论一下即可. void p ...

  8. 洛谷P2894 [USACO08FEB]酒店Hotel [线段树]

    题目传送门 酒店 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and ...

  9. [USACO08FEB]酒店Hotel 线段树 BZOJ 1593

    题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...

  10. luogu P2894 [USACO08FEB]酒店Hotel

    题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a ...

随机推荐

  1. Delphi下OpenGL2d绘图(02)-画点

    一.前言 图形的绘制可以使用glBegin().glEnd()之间完成,绘制的框架代码可以使用 Delphi下OpenGL2d绘图(01)-初始化 中的代码.修改的部份为 Draw 函数的内容. 二. ...

  2. IE10 CSS Hack(顺便聊聊IE11的CSS Hack)

    一.特性检测:@cc_on 我们可以用IE私有的条件编译(conditional compilation)结合条件注释来提供针对ie10的Hack:该脚本里面的IE排除条件注释,以确保IE6-9不承认 ...

  3. 获取URL中某个参数的值

    JS代码: function getQueryString(name){ var reg = new RegExp("(^|&)" + name + "=([^& ...

  4. 100个实用的CSS技巧,以及遇见的问题和解决方案。

    前言 本篇文章将会持续更新,我会将我遇见的一些问题,和我看到的实用的CSS技巧记录下来,本篇文章会以图文混排的方式写下去.具体什么时候写完我也不清楚,反正我的目标是写100个.  本案例都是经本人实测 ...

  5. 登陆oracle数据库时提示“ORA-28002: 7 天之后口令将过期” 或提示 密码过期

    登陆oracle数据库时提示“ORA-28002: 7 天之后口令将过期” 或提示 密码过期. [原因/触发因素] 确定是由于oracle11g中默认在default概要文件中设置了“PASSWORD ...

  6. Java String、string[]、List初始化方法

    String初始化: 1.String str = new String("string1"); 2.String str = "string1"; Strin ...

  7. jquery点击导航栏选中更换样式

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. npm安装指定版本

    今天犯了一个低级错误,在npm安装依赖时,命令写成下了格式 npm i --save iview 2.0.0 要安装指定版本应该使用 npm i --save iview@2.0.0 谨记

  9. 织梦后台添加友情链接的方法(flink标签)

    标记名称:flink[标签简介][功能说明]:用于获取友情链接,其对应后台文件为"includetaglibflink.lib.php".[适用范围]:全局标记,适用V55,V56 ...

  10. .NET开源工作流RoadFlow-流程运行-任务收回

    如果一个任务则发送,又觉得还要想修改可以立即收回刚刚发送的任务. 任务收回条件:任务发送后下一步处理人还没有打开该任务,则在已办事项中会看到 收回 按钮,否则不能收回. 点击收回按钮再确认即可收回刚刚 ...