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;
    }

      

  • 相关阅读:
    Oracle 正则表达式函数-REGEXP_SUBSTR 使用例子
    Oracle 正则表达式函数-REGEXP_INSTR 使用例子
    Oracle 正则表达式函数-REGEXP_LIKE 使用例子
    Oracle 正则表达式函数-REGEXP_REPLACE 使用例子
    依赖注入和控制反转的理解
    Kindle 推送教程:教你用电子邮箱推送电子书(Kindle伴侣)
    gradle基础的build文件模板_jetty
    SSO
    ElasticSearch1.7 java api
    Ubuntu mysql
  • 原文地址:https://www.cnblogs.com/yuecxl/p/2418198.html
Copyright © 2011-2022 走看看