zoukankan      html  css  js  c++  java
  • [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
  • 相关阅读:
    前端常用布局
    Vue, React, AngularJS, Angular2 我们对流行JavaScript框架们的选择
    使用vue-cli创建vue项目
    Null component Catalina
    初识MongoDB
    小米平板2 win10 MIUI互刷教程
    tomcat报错
    websocket
    前后端数据交互方法
    二叉排序树
  • 原文地址:https://www.cnblogs.com/mrclr/p/9691656.html
Copyright © 2011-2022 走看看