zoukankan      html  css  js  c++  java
  • [转]poj 1823 Hotel 线段树

    线段树。
    题意是给出一个长为N的区间,不断进行三中操作:
    1.插入一个区间,所有被插入的地方都表示占有;
    2.删除一个区间,所有删除的地方都表示释放;
    3.询问整个范围内最长的连续的空区间的长度。
    很明显的线段树,可惜我想错了,以为入区间的最大值可以独立的从两个子区间中寻找,忘记了两个子区间合并后可能得到一个更长的区间,尝试好多数据都对,提交就是WA,看网上的做法跟我的差别很大,也没心情看。搁置了好几天,今天终于发现原来自己从开始就把算法想错了,而不是代码的问题,白查了那么久,理解还是不够深啊。

     

    #include<iostream>
    #include<string>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<cmath>
    #include<set>
    #include<map>
    #include<vector>
    #include<fstream>
    #include<sstream>
    #include<iomanip>
    using namespace std;
    const int N = 16001;
    const int M = 101;
    const int MAX = 1000000000;
    struct node
    {
    int l,r;//denotes the bound of the segment
    int la,ra,ma;//denotes the the bound of max free segment in this segment
    int f;//denotes if the segment is 2 full used or 0 free or 1 partial used
    }t[4*N];
    void build(int i, int l, int r)
    {
    t[i].l = l;
    t[i].r = r;
    t[i].f = 0;
    if(l == r)return;
    int mid = (l+r)>>1;
    build(i<<1, l, mid);
    build((i<<1)+1, mid+1, r);
    }
    void insert(int i, int l, int r)
    {
    if(t[i].l == l && t[i].r == r)
    {
    t[i].f = 2;
    t[i].ma = t[i].la = t[i].ra = 0;
    return;
    }
    int x;
    if(t[i].f == 0)
    {
    x = (i<<1);
    t[i].f = 1;
    t[x].f = 0;
    t[x+1].f = 0;
    t[x].la = t[x].ma = t[x].ra = t[x].r-t[x].l+1;
    x++;
    t[x].la = t[x].ma = t[x].ra = t[x].r-t[x].l+1;
    }
    int mid = (t[i].l + t[i].r)>>1;
    if(r <= mid)
    {
    insert(i<<1, l, r);
    }
    else if(l > mid)
    {
    insert((i<<1)+1, l, r);
    }
    else
    {
    insert(i<<1, l, mid);
    insert((i<<1)+1, mid+1, r);
    }
    //the key oprations
    x = i<<1;
    if(t[x].f == 0)
    {
    t[i].la = t[x].ma + t[x+1].la;
    }
    else
    {
    t[i].la = t[x].la;
    }
    x++;
    if(t[x].f == 0)
    {
    t[i].ra = t[x-1].ra + t[x].ma;
    }
    else
    {
    t[i].ra = t[x].ra;
    }
    int a,b,c;
    a = max(t[i<<1].ma,t[(i<<1)+1].ma);
    b = t[i<<1].ra + t[(i<<1)+1].la;
    c = max(t[i].la, t[i].ra);
    t[i].ma = max(max(a,b),c);
    if(t[i<<1].f == t[(i<<1)+1].f)
    {
    t[i].f = t[i<<1].f;
    }
    }
    void remove(int i, int l, int r)
    {
    if(t[i].l == l && t[i].r == r)
    {
    t[i].f = 0;
    t[i].ma = t[i].la = t[i].ra = r-l+1;
    return;
    }
    int x;
    if(t[i].f == 2)
    {
    x = (i<<1);
    t[i].f = 1;
    t[x].f = 2;
    t[x+1].f = 2;
    t[x].la = t[x].ma = t[x].ra = 0;
    x++;
    t[x].la = t[x].ma = t[x].ra = 0;
    }
    int mid = (t[i].l + t[i].r)>>1;
    if(r <= mid)
    {
    remove(i<<1, l, r);
    }
    else if(l > mid)
    {
    remove((i<<1)+1, l, r);
    }
    else
    {
    remove(i<<1, l, mid);
    remove((i<<1)+1, mid+1, r);
    }
    //the key oprations
    x = i<<1;
    if(t[x].f == 0)
    {
    t[i].la = t[x].ma + t[x+1].la;
    }
    else
    {
    t[i].la = t[x].la;
    }
    x++;
    if(t[x].f == 0)
    {
    t[i].ra = t[x-1].ra + t[x].ma;
    }
    else
    {
    t[i].ra = t[x].ra;
    }
    int a,b,c;
    a = max(t[i<<1].ma,t[(i<<1)+1].ma);
    b = t[i<<1].ra + t[(i<<1)+1].la;
    c = max(t[i].la, t[i].ra);
    t[i].ma = max(max(a,b),c);
    if(t[i<<1].f == t[(i<<1)+1].f)
    {
    t[i].f = t[i<<1].f;
    }
    }
    int main()
    {
    int n,p,c,a,b;
    while(scanf("%d%d",&n,&p) != EOF)
    {
    build(1,1,n);
    t[1].f = 0;
    t[1].ma = t[1].la = t[1].ra = n;
    while(p--)
    {
    scanf("%d",&c);
    if(c == 1)
    {
    scanf("%d%d",&a,&b);
    if(b == 0)continue;
    insert(1,a,a+b-1);
    }
    else if(c == 2)
    {
    scanf("%d%d",&a,&b);
    remove(1,a,a+b-1);
    }
    else
    {
    printf("%d\n",t[1].ma);
    }
    }
    }
    return 0;
    }

     

  • 相关阅读:
    C# String.Format用法和格式说明
    VS2017桌面应用程序打包成.msi或者.exe
    Mysql授权允许远程访问
    C# Winform频繁刷新导致界面闪烁解决方法
    C# 解决窗体闪烁
    C# winform或控制台Properties.Settings.Default的使用及存储位置
    C# 获取计算机cpu,硬盘,内存相关的信息
    C# 多线程多文件批量下载---子线程中更新UI 实例
    Objective-C:NSSet和NSMutbaleSet的用法
    iOS:App上架流程和支付宝支付流程
  • 原文地址:https://www.cnblogs.com/lzhitian/p/2610500.html
Copyright © 2011-2022 走看看