zoukankan      html  css  js  c++  java
  • HDU_2871 线段树+vecor的中间插入和删除使用

    本来这个题目就是个合并区间的题,就跟Hotel一样,要插入一段,则找左孩子 合并后的中间区间 右孩子,但是比较恶心的是,他需要实时得到某一段的起终点,或者某个点在第几个段里面,我想过在线段树里面加入几个变量来记录左右边界,发现还是不行,因为还要可以消除某个区间段

    后来找博客发现向量原来还可以动态的插入和删除,那我把每一块的起终点放在向量里面,既能有序的进行查找,又能再Free操作的时候,直接马上把这个区间抹除,解决了这个问题,其他就跟Hotel区间查询 和 懒惰标记是一样的了,由于向量里面存储的是有序的,所以用二分进行查找

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define N 50010
    using namespace std;
    typedef pair<int,int> pill;
    vector<pill> till;
    int mc[N*3],lc[N*3],rc[N*3],flag[N*3];
    int n,m;
    int max(int a,int b) {return a>b? a:b;}
    void up(int rt,int l,int r)
    {
        int ll=rt<<1,rr=rt<<1|1;
        mc[rt]=max(mc[ll],mc[rr]);
        lc[rt]=lc[ll];rc[rt]=rc[rr];
        int mid=(l+r)>>1;
        if (lc[rt]==mid-l+1) lc[rt]+=lc[rr];
        if (rc[rt]==r-mid)   rc[rt]+=rc[ll];
        if (lc[rr]+rc[ll]>mc[rt]){
            mc[rt]=lc[rr]+rc[ll];
        }
    }
    void build(int rt,int l,int r)
    {
        flag[rt]=-1;
        if (l>=r){
            mc[rt]=lc[rt]=rc[rt]=1;
            return;
        }
        int mid=(l+r)>>1;
        build(lson);
        build(rson);
        up(rt,l,r);
    }
    void pushdown(int rt,int l,int r){
        if (flag[rt]==-1 || l>=r) return;
        int mid=(l+r)>>1;
        mc[rt<<1]=(mid-l+1)*flag[rt];
        mc[rt<<1|1]=(r-mid)*flag[rt];
        lc[rt<<1]=rc[rt<<1]=(mid-l+1)*flag[rt];
        lc[rt<<1|1]=rc[rt<<1|1]=(r-mid)*flag[rt];
        flag[rt<<1]=flag[rt<<1|1]=flag[rt];
        flag[rt]=-1;
    }
    void cover(int L,int R,int rt,int l,int r,int rec){
        int mid=(l+r)>>1;
        if (L<=l && r<=R){
            flag[rt]=rec;
            mc[rt]=lc[rt]=rc[rt]=(r-l+1)*flag[rt];
            return;
        }
        if (flag[rt]!=-1) pushdown(rt,l,r);
        if (L<=mid) cover(L,R,lson,rec);
        if (R>mid) cover(L,R,rson,rec);
        up(rt,l,r);
    }
    int query(int x,int rt,int l,int r)
    {
        pushdown(rt,l,r);
        if (l>=r) return l;
        int mid=(l+r)>>1;
        if (mc[rt<<1]>=x) return query(x,lson);
        if (lc[rt<<1|1]+rc[rt<<1]>=x) return mid-rc[rt<<1]+1;
        return query(x,rson);
    }
    int bs(int x)
    {
        int l=0,r=till.size()-1,mid;
        while (l<=r){
            mid=(l+r)>>1;
            if (till[mid].first<=x) l=mid+1;
            else r=mid-1;
        }
        return l;
    }
    void solve(char* ch)
    {
        if (ch[0]=='R'){
                till.clear();
                cover(1,n,1,1,n,1);
                puts("Reset Now");
                return;
        }
        int d;
        scanf("%d",&d);
        if (ch[0]=='N'){
                 if (mc[1]<d) {puts("Reject New");return;}
                int sta=query(d,1,1,n);
                printf("New at %d
    ",sta);
                int a=bs(sta);
                pill c;c.first=sta;c.second=sta+d-1;
                till.insert(till.begin()+a,c);
                cover(sta,sta+d-1,1,1,n,0);
                return;
        }
        if (ch[0]=='F'){
            int id=bs(d);
            id--;
            if (id<=-1||till[id].second<d) puts("Reject Free");
            else{
                printf("Free from %d to %d
    ",till[id].first,till[id].second);
                cover(till[id].first,till[id].second,1,1,n,1);
                till.erase(till.begin()+id);
            }
            return;
        }
        if (ch[0]=='G')
        {
            if (d > till.size())
                printf("Reject Get
    ");
             else printf("Get at %d
    ", till[d-1].first);
        }
    }
    int main()
    {
        char ch[8];
        while (scanf("%d%d",&n,&m)!=EOF)
        {
            build(1,1,n);
            till.clear();
            for (int q=0;q<m;q++){
             scanf("%s",ch);
             solve(ch);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    python 按行读取判断是否为空
    python获取目录下所有文件
    Kolakoski
    最小背包问题
    python 求第k个最大数
    python 求最大子序列
    爬取数据的程序
    文件对比程序
    trsd_extract_EDSD_new
    tred_extract_EDED_new
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3718271.html
Copyright © 2011-2022 走看看