zoukankan      html  css  js  c++  java
  • poj3667 hotel

    这题目的解决方案关键是怎样制造连续的区域来判断是否符合要求。 你查找最大的区域时, 可以分为三个部分, 一个是左子树的最大连续区域, 一个是右子树最大区域, 一个 是左子树从右向左最大的连续区域加上右子树从左向右的最大区域

     
     
    View Code
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #define maxn 200008

    struct node
    {
    int lval, rval, val;
    int left, right;
    int count;

    void init(int x)
    {
    lval = rval = val = x * count;
    }
    }map[maxn];

    inline int max(int x, int y)
    {
    return x > y? x:y;
    }

    void build(int left, int right, int side)
    {
    map[side].left = left;
    map[side].right = right;
    map[side].count = right - left + 1;
    map[side].init(1);

    if (left == right)
    {
    return;
    }

    int mid = (left + right) >> 1;
    build(left, mid, side << 1);
    build(mid + 1, right, side << 1 | 1);
    return;
    }

    void update(int left, int right, int flag, int side)
    {
    int lchild, rchild;
    lchild = side << 1;
    rchild = side << 1 | 1;

    if (map[side].left > right || map[side].right < left)
    {
    return;
    }
    if (left <= map[side].left && right >= map[side].right)
    {
    map[side].init(flag);
    return;
    }
    if (map[side].val == map[side].count )
    {
    if (flag == 1)
    {
    return;
    }
    else
    {
    map[lchild].init(1);
    map[rchild].init(1);
    }
    }
    if (map[side].val == 0)
    {
    map[lchild].init(0);
    map[rchild].init(0);
    }
    int mid = (map[side].left + map[side].right) >> 1;
    if (mid >= right)
    {
    update(left, right, flag, lchild);
    }
    else if (left > mid )
    {
    update(left, right, flag, rchild);
    }
    else
    {
    update(left, mid, flag, lchild);
    update(mid + 1, right, flag, rchild);
    }

    // left
    map[side].lval = map[rchild].lval + (map[rchild].val == map[rchild].count ? map[lchild].lval:0);

    // right
    map[side].rval = map[lchild].rval + (map[lchild].val == map[lchild].count? map[rchild].rval:0);

    //current
    map[side].val = max(map[lchild].lval+map[rchild].rval, max(map[lchild].val, map[rchild].val));

    return ;
    }

    int find(int val, int side)
    {
    if (map[side].val < val)
    {
    return 0;
    }

    if (map[side].val == map[side].count)
    {
    return map[side].left;
    }

    if (map[side].rval >= val)
    {
    return map[side].left;
    }

    if (map[side << 1].val >= val)
    {
    return find(val, side << 1);
    }
    if (map[side << 1].lval + map[side << 1 | 1].rval >= val)
    {
    return map[side << 1].right - map[side << 1].lval + 1;
    }
    return find(val, side << 1 | 1);
    }

    void print(int m)
    {
    int choice, x, y;

    for (int i = 0; i < m; i ++)
    {
    scanf("%d", &choice);
    if (choice == 1)
    {
    scanf("%d", &x);
    choice = find(x, 1);
    printf("%d\n", choice);
    if (choice > 0)
    {
    update(choice, choice + x - 1, 0, 1);
    }
    }
    else
    {
    scanf("%d%d", &x, &y);
    update(x, x + y - 1, 1, 1);
    }
    }
    return ;
    }

    int main()
    {
    int n, m;

    scanf("%d%d", &n, &m);
    build(1, n, 1);
    print(m);

    return 0;
    }

      

  • 相关阅读:
    winform+c#之窗体之间的传值 Virus
    ASP.NET 2.0 利用 checkbox获得选中行的行号, 在footer中显示 Virus
    .NET中的winform的listview控件 Virus
    我的书橱
    Expert .NET 2.0 IL Assembler·译者序一 写在一稿完成之即
    Verbal Description of Custom Attribute Value
    AddressOfCallBacks in TLS
    下一阶段Schedule
    2008 Oct MVP OpenDay 第二天 博客园聚会
    2008 Oct MVP OpenDay 第二天 颁奖·讲座·晚会
  • 原文地址:https://www.cnblogs.com/yuecxl/p/2418198.html
Copyright © 2011-2022 走看看