[USACO08FEB]酒店Hotel

嘟嘟嘟

这道题以前在学校内网刷过类似的,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格式,代码缩进很丑

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<stack>
  9 #include<queue>
 10 #include<vector>
 11 using namespace std;
 12 #define enter puts("")
 13 #define space putchar(‘ ‘)
 14 #define Mem(a, x) memset(a, x, sizeof(a))
 15 #define rg register
 16 typedef long long ll;
 17 typedef double db;
 18 const int INF = 0x3f3f3f3f;
 19 const db eps = 1e-8;
 20 const int maxn = 5e4 + 5;
 21 inline ll read()
 22 {
 23   ll ans = 0;
 24   char ch = getchar(), las = ‘ ‘;
 25   while(!isdigit(ch)) las = ch, ch = getchar();
 26   while(isdigit(ch)) ans = (ans << 3) + (ans << 1) + ch - ‘0‘, ch = getchar();
 27   if(las == ‘-‘) ans = -ans;
 28   return ans;
 29 }
 30 inline void write(ll x)
 31 {
 32   if(x < 0) putchar(‘-‘), x = -x;
 33   if(x >= 10) write(x / 10);
 34   putchar(x % 10 + ‘0‘);
 35 }
 36
 37
 38 int n, m;
 39
 40 struct Tree
 41 {
 42   int l, r, lzy;
 43   int lmax, rmax, imax;
 44   Tree operator + (const Tree& other)const
 45   {
 46     Tree ret;
 47     ret.l = l; ret.r = other.r;
 48     ret.lzy = -1;
 49     ret.lmax = lmax;
 50     if(lmax == r - l + 1) ret.lmax += other.lmax;
 51     ret.rmax = other.rmax;
 52     if(other.rmax == other.r - other.l + 1) ret.rmax += rmax;
 53     ret.imax = max(max(imax, other.imax), rmax + other.lmax);
 54     return ret;
 55   }
 56 }t[maxn << 2];
 57 void build(int L, int R, int now)
 58 {
 59   t[now].l = L; t[now].r = R;
 60   t[now].lzy = -1;
 61   t[now].lmax = t[now].rmax = t[now].imax = R - L + 1;
 62   if(L == R) return;
 63   int mid = (L + R) >> 1;
 64   build(L, mid, now << 1);
 65   build(mid + 1, R, now << 1 | 1);
 66 }
 67 void pushdown(int now)
 68 {
 69   if(t[now].lzy != -1)
 70     {
 71       t[now << 1].lmax = t[now << 1].rmax = t[now << 1].imax = (t[now << 1].r - t[now << 1].l + 1) * (t[now].lzy ^ 1);
 72       t[now << 1 | 1].lmax = t[now << 1 | 1].rmax = t[now << 1 | 1].imax = (t[now << 1 | 1].r - t[now << 1 | 1].l + 1) * (t[now].lzy ^ 1);
 73       t[now << 1].lzy = t[now << 1 | 1].lzy = t[now].lzy;
 74       t[now].lzy = -1;
 75     }
 76 }
 77 void update(int L, int R, int now, int flg)
 78 {
 79   if(L == t[now].l && R == t[now].r)
 80     {
 81       t[now].lmax = t[now].rmax = t[now].imax = (R - L + 1) * (flg ^ 1);
 82       t[now].lzy = flg; return;
 83     }
 84   pushdown(now);
 85   int mid = (t[now].l + t[now].r) >> 1;
 86    if(R <= mid) update(L, R, now << 1, flg);
 87    else if(L > mid) update(L, R, now << 1 | 1, flg);
 88    else update(L, mid, now << 1, flg), update(mid + 1, R, now << 1 | 1, flg);
 89    t[now] = t[now << 1] + t[now << 1 | 1];
 90 }
 91 int query(int len, int now)
 92 {
 93   if(t[now].imax < len) return 0;
 94   pushdown(now);
 95   if(t[now].lmax >= len) return t[now].l;
 96   else if(t[now << 1].imax >= len) return query(len, now << 1);
 97   else if(t[now << 1].rmax + t[now << 1 | 1].lmax >= len) return t[now << 1].r - t[now << 1].rmax + 1;
 98   else return query(len, now << 1 | 1);
 99 }
100
101 int main()
102 {
103   n = read(); m = read();
104   build(1, n, 1);
105   for(int i = 1; i <= m; ++i)
106     {
107       int d = read();
108       if(d == 1)
109     {
110       int x = read();
111       int ans = query(x, 1);
112       write(ans); enter;
113       if(ans) update(ans, ans + x - 1, 1, 1);
114     }
115       else
116     {
117       int L = read(), len = read();
118       update(L, L + len - 1, 1, 0);
119     }
120     }
121   return 0;
122 }

原文地址:https://www.cnblogs.com/mrclr/p/9691656.html

时间: 2024-10-12 04:12:45

[USACO08FEB]酒店Hotel的相关文章

P2894 [USACO08FEB]酒店Hotel

P2894 [USACO08FEB]酒店Hotel 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on fam

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

今天我们说说线段树. 我个人还是非常欣赏这种数据结构的.(逃)因为它足够优美,有递归结构,有左子树和右子树,还有二分的思想. emm这个文章打算自用,就不写那些基本的操作了... 1° 简单的懒标记(仅含加法) 当我们进行区间修改(比如同时加上一个数)时,我们现在也许暂时不用它,可以当需要用的时候再改.这个时候我们就需要做个标记,这个标记就是懒标记,$lazy$.如果在后续的指令中需要从p向下递归,我们这时候检查它是否有标记.若有,就按照标记更新两个子节点,同时为子节点增加标记,清除p的标记.

[P2894][USACO08FEB] 酒店Hotel (线段树+懒标记下传)

题意:有 n个房间,题目给出两个操作,若 op==1,就输出最靠左的连续空房数量为 x的房间序列的最左边的序号,然后将这些房间改为入住:若 op==2,就将从 x~y的的序列全部改为空房: 解法:线段树+懒标记下传: 1.线段树:题目让在一个很长的序列操作很多次,暴力显然过不了,要用线段树优化: 2.懒标记下传:这是本题的精髓.   此题要维护的不是序列上的数值总和,而是该序列的最长连续空房的长度 sum,从该节点从左向右数最长的连续空房长度 lm,以及从该节点从右向左数最长的连续空房长度 rm

word20170105订酒店 hotel reservation有用的词和句子

有用的词: hotel reservation/booking: 酒店预订 standard room:标准间 suite: 套房 king size bed: 大床房 double bed:双床房 extra bed/cot: 加床 crib: 宝宝床.婴儿床 checking in on...checking out on...: 某日入住,某日离店 breakfast included: 包早餐 free cancellation: 免费取消 incidental deposit/char

计划做题列表

估计是做不完.. emmmm  不用估计,是肯定 马上就滚回去学文化课了.... ....列表全都是数据结构... mdzz 我可能是傻了 1.数学  P1214 [USACO1.4]等差数列 Arithmetic Progressions https://www.luogu.org/problemnew/show/P1214 2.P4243 [JSOI2009]等差数列 线段树 https://www.luogu.org/problemnew/show/P4243 主席树 P3313 [SDO

第七章 springboot + retrofit

retrofit:一套RESTful架构的Android(Java)客户端实现. 好处: 基于注解 提供JSON to POJO,POJO to JSON,网络请求(POST,GET,PUT,DELETE等)封装 可以看做是对HttpClient的再次封装 1.为了做测试,建立了一个新的springboot项目"myboot2",项目结构如下: 1.1.pom.xml 1 <?xml version="1.0" encoding="UTF-8&quo

浅谈线段树

 数据结构——线段树 O.引例 A.给出n个数,n<=100,和m个询问,每次询问区间[l,r]的和,并输出. 一种回答:这也太简单了,O(n)枚举搜索就行了. 另一种回答:还用得着o(n)枚举,前缀和o(1)就搞定. 那好,我再修改一下题目. B.给出n个数,n<=100,和m个操作,每个操作可能有两种:1.在某个位置加上一个数:2.询问区间[l,r]的和,并输出. 回答:o(n)枚举. 动态修改最起码不能用静态的前缀和做了. 好,我再修改题目: C.给出n个数,n<=1000000,

第七章 springboot + retrofit(转载)

本篇博客转发自:http://www.cnblogs.com/java-zhao/p/5350861.html retrofit:一套RESTful架构的Android(Java)客户端实现. 好处: 基于注解 提供JSON to POJO,POJO to JSON,网络请求(POST,GET,PUT,DELETE等)封装 可以看做是对HttpClient的再次封装 1.为了做测试,建立了一个新的springboot项目"myboot2",项目结构如下: 1.1.pom.xml <

第十六章 springboot + OKhttp + String.format

模拟浏览器向服务器发送请求四种方式: jdk原生的Http包下的一些类 httpclient(比较原始,不怎么用了):第一章 HttpClient的使用 Okhttp(好用,推荐) retrofit(好用,推荐),用法:第七章 springboot + retrofit 看本章之前可以先看看第七章 springboot + retrofit 1.myboot2项目 1.1.application.properties 1 server.port=8081 注意:指定服务器启动端口的有三种方式 在