[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 }
View Code

 

posted @ 2018-09-23 13:07  mrclr  阅读(386)  评论(0编辑  收藏  举报