poj 3667 區間合并 區間線段樹

來源:互聯網
上載者:User

/*
    區間線段樹  區間合并
    題意:Hotel有N房間,兩種操作:一種checkin(x),某個團的x個人要住連續的x間房間(k,k+1,..,k+x-1),若有合適的房間則輸出最小房間編號k,否>則0,表示謝絕這個團的生意。另一種checkout(x,y),原住x,x+1,..,x+y-1的人要離開,則這些房間就空了出來,這裡面可能有一些原本就是空的。

    思路:經典區間線段樹。維護這麼幾個值:
    Seg_tree_Node {
        int l, r;
        int l_rest, r_rest; 以l為起點的連續空餘房間數,以r為終點的連續空餘房間數
        int max, max_pos;   區間最多的連續空餘房間數,以及對應的最小編號。
        int add;   for lazy.._zZ
    }

    Query的順序為:<1>有合適的房間?f[1].max >= need ?
                   <1.5> 如果f[u].max == need 則直接返回f[u].max_pos
                   <2>u的左節點l_child, l_child.max >= need ? 是就進左節點
                   <3>u的左右節點交界處?
                   <4>上面都不行的話就進右節點吧
    養成了風格,當有lazy來時如果要保持當前節點的屬性為最新,則需要更新當前節點屬性,我用put_self()。
    下降lazy用put_down(),有時在Update()時下降,有時在Query()時也要下降。
    Update的最後總會有個put_up()

*/


#include <stdio.h>#define     debug       printf("!\n")#define     MAXN        50005 #define     MID(x, y)   (((x)+(y)) >> 1LL)#define     L(x)        ((x)<<1LL)#define     R(x)        (((x)<<1LL)|1LL)struct Node {    int l, r, l_rest, r_rest, max, max_pos, add;} f[MAXN << 2];void Update(int, int, int, int);void put_up(int u){    Node & a = f[u];    Node & ll = f[L(u)];    Node & rr = f[R(u)];    if(ll.max >= rr.max) {        a.max = ll.max;        a.max_pos = ll.max_pos;    } else {        a.max = rr.max;        a.max_pos = rr.max_pos;    }    a.l_rest = ll.l_rest;           //小錯誤大煩惱...因為一個字母拼錯了,debug了好久!    a.r_rest = rr.r_rest;    if(ll.r_rest != 0 && rr.l_rest != 0) {        if(a.max < ll.r_rest + rr.l_rest || (a.max == ll.r_rest + rr.l_rest && a.max_pos > ll.r - ll.r_rest + 1)) {            a.max = ll.r_rest + rr.l_rest;            a.max_pos = ll.r - ll.r_rest + 1;        }        if(ll.l_rest == ll.r - ll.l + 1) a.l_rest = ll.l_rest + rr.l_rest;        if(rr.r_rest == rr.r - rr.l + 1) a.r_rest = rr.r_rest + ll.r_rest;    }}void build(int u, int l, int r){    f[u].l = l, f[u].r = r, f[u].add = 0;    if(l == r) {        f[u].max = f[u].l_rest = f[u].r_rest = 1;        f[u].max_pos = l;        return ;    }    int mid = MID(l, r);    build(L(u), l, mid);    build(R(u), mid+1, r);    put_up(u);}void put_down(int u){    int mid = MID(f[u].l, f[u].r);    Update(L(u), f[u].l, mid, f[u].add);    Update(R(u), mid+1, f[u].r, f[u].add);    f[u].add = 0;}void put_self(int u){    Node & a = f[u];    a.max_pos = a.l;    a.max = a.l_rest = a.r_rest = (a.r - a.l + 1) * (int)(a.add == 1);}void Update(int u, int l, int r, int add){    if(l == f[u].l && f[u].r == r) {        f[u].add = add ;        put_self(u);        return ;    }    if(f[u].add) put_down(u);    int mid = MID(f[u].l , f[u].r);    if(r <= mid) Update(L(u), l, r, add);    else if(mid < l) Update(R(u), l, r, add);    else Update(L(u), l, mid, add), Update(R(u), mid+1, r, add);    put_up(u);}int  Query(int u, int need){    Node & ll = f[L(u)];    Node & rr = f[R(u)];    if(f[u].max == need) return f[u].max_pos;           //MARK  呆會兒看看max的更新     //感覺這句不影響吧..    if(f[u].add) put_down(u);    if(ll.max >= need) return Query(L(u), need);    else if(ll.r_rest + rr.l_rest >= need) return ll.r - ll.r_rest + 1;    else return Query(R(u), need);}int main(){    int query, n, op, need, l, r;    scanf("%d%d", &n, &query);    build(1, 1, n);    while(query--) {        scanf("%d", &op);        if(op == 1) {            scanf("%d", &need);            if(f[1].max < need) printf("0\n");            else {                int result = Query(1, need);                if(result) Update(1, result, result+need-1, 2);                printf("%d\n", result);            }        } else {            scanf("%d%d", &l, &r);            Update(1, l, r+l-1, 1);        }    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.