寒假刷題30:洛谷P2161 [SHOI2009]會場預約(線段樹)

題目鏈接:

P2161 [SHOI2009]會場預約

題目解析:

聽說是平衡樹的題(然鵝我是在線段樹樹狀數組分類裏找到的它)
線段樹做法:把題目看成一個僅實現區間修改的線段樹,用tagtag數組打打標記即可
有空補一下平衡樹樹狀數組做法吧…好像還有一個神奇的STL做法?
翻譯:一定不咕一定不咕

AC代碼(線段樹):

#include<cstdio>
#define N 100200
#define ls i<<1
#define rs i<<1|1
int min(int a,int b) {return a>b?b:a;}
int max(int a,int b) {return a>b?a:b;}
struct data{
    int cnt,ml,mr,lc,rc;
    data operator + (const data &b) {return (data){(cnt&&b.cnt)?cnt+b.cnt-(rc&&(rc==b.lc)):cnt+b.cnt,min(ml,b.ml),max(mr,b.mr),lc,b.rc};}
    void clear() {ml=mr=lc=rc=cnt=-1;}
};
struct segmenttree{
    data tree[N<<3],tag[N<<3];
    void pushdown(int i)
    {
        if (!~tag[i].cnt) return;
        tree[ls].lc=tree[ls].rc=tree[rs].lc=tree[rs].rc=tag[i].cnt;
        if (tag[i].cnt)
        {
            tree[rs].cnt=tree[ls].cnt=1;
            tree[rs].ml=tree[ls].ml=tag[i].ml;
            tree[rs].mr=tree[ls].mr=tag[i].mr;
            tag[ls]=tag[rs]=tag[i];
        }
        else
        {
            int mid=(tag[i].ml+tag[i].mr)>>1;
            tree[rs].cnt=tree[ls].cnt=0;
            tree[ls].ml=tag[i].ml;
            tree[rs].ml=mid+1;
            tree[rs].mr=tag[i].mr;
            tree[ls].mr=mid;
            tag[ls]=tag[rs]=tag[i];
            tag[ls].mr=mid;tag[rs].ml=mid+1;
        }
        tag[i].clear();
    }
    void update(int i,int l,int r,int L,int R,int c)
    {
        if (L<=l&&r<=R)
        {
            tree[i].lc=tree[i].rc=c;
            tag[i].cnt=c;
            if (c)
            {
                tree[i].cnt=1;
                tree[i].ml=L;tree[i].mr=R;
                tag[i].ml=L;tag[i].mr=R;
            }
            else
            {
                tree[i].cnt=0;
                tree[i].ml=l;tree[i].mr=r;
                tag[i].ml=l;tag[i].mr=r;
            }
            return;
        }
        int mid=(l+r)>>1;
        pushdown(i);
        if (L<=mid) update(ls,l,mid,L,R,c);
        if (mid<R) update(rs,mid+1,r,L,R,c);
        tree[i]=tree[ls]+tree[rs];
    }
    data query(int i,int l,int r,int L,int R)
    {
        if (L<=l&&r<=R) return tree[i];
        pushdown(i);
        int mid=(l+r)>>1;
        if (mid<L) return query(rs,mid+1,r,L,R);
        if (mid>=R) return query(ls,l,mid,L,R);
        return query(ls,l,mid,L,mid)+query(rs,mid+1,r,mid+1,R);
    }
    void build(int i,int l,int r)
    {
        tag[i].clear();
        if (l==r)
        {
            tree[i].cnt=0;
            tree[i].lc=tree[i].rc=0;
            tree[i].ml=tree[i].mr=l;
            return;
        }
        int mid=(l+r)>>1;
        build(ls,l,mid);build(rs,mid+1,r);
        tree[i]=tree[ls]+tree[rs];
    }
}cof;
int main()
{
    int n,l,r;char a;
    scanf("%d",&n);
    cof.build(1,1,100000);
    while(n--)
    {
        while(a=getchar()) if (a=='A'||a=='B') break;
        if (a=='A')
        {
            scanf("%d%d",&l,&r);
            data tmp=cof.query(1,1,100000,l,r);
            printf("%d\n",tmp.cnt);
            cof.update(1,1,100000,tmp.ml,tmp.mr,0);
            cof.update(1,1,100000,l,r,n);
        }
        else
        {
            data tmp=cof.query(1,1,100000,1,100000);
            printf("%d\n",tmp.cnt);
        } 
    }
    return 0;
}
發佈了60 篇原創文章 · 獲贊 23 · 訪問量 6598
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章