zoukankan      html  css  js  c++  java
  • 线段树 HDU 2871

    题意还是清楚的

    就是维护很麻烦

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    
    using namespace std;
    
    #define MAXN 50010
    
    struct node
    {
        int l,r,la;
        int ls,rs,ms;
    }x[MAXN<<3];
    struct no
    {
        int l,r;
    };
    int n,m;
    vector<no>z;
    
    void Build(int l,int r,int a)
    {
        x[a].l=l;
        x[a].r=r;
        x[a].la=-1;
        x[a].ls=x[a].rs=x[a].ms=r-l+1;
        if(l == r)
            return ;
        int mid=(l+r)>>1;
        Build(l,mid,a<<1);
        Build(mid+1,r,a<<1|1);
    }
    char s1[10];
    void push_down(int a)//下更
    {
        x[a<<1].la=x[a<<1|1].la=x[a].la;
        int r,l,mid;
        l=x[a].l;
        r=x[a].r;
        mid=(r+l)>>1;
        if(x[a].la==1)
        {
            x[a<<1].ls=x[a<<1].rs=x[a<<1].ms=mid-l+1;
            x[a<<1|1].ls=x[a<<1|1].rs=x[a<<1|1].ms=r-mid;
        }
        else
        {
            x[a<<1].ls=x[a<<1].rs=x[a<<1].ms=0;
            x[a<<1|1].ls=x[a<<1|1].rs=x[a<<1|1].ms=0;
        }
        x[a].la=-1;
    }
    void push_up(int a)//上更
    {
        x[a].ls=x[a<<1].ls;
        if(x[a].ls==x[a<<1].r-x[a<<1].l+1)
            x[a].ls+=x[a<<1|1].ls;
        x[a].rs=x[a<<1|1].rs;
        if(x[a].rs==x[a<<1|1].r-x[a<<1|1].l+1)
            x[a].rs+=x[a<<1].rs;
        x[a].ms=max(x[a<<1].ms,x[a<<1|1].ms);
        x[a].ms=max(x[a].ms,x[a<<1].rs+x[a<<1|1].ls);
    }
    int Ques(int a,int len)
    {
        if(x[a].la!=-1)
            push_down(a);
        int mid=(x[a].r+x[a].l)>>1;
        if(x[a].ms<len)
            return 0;
        else
        {
            if(x[a].ls>=len)  //这4个很重要
                return x[a].l;
            else if(x[a<<1].ms>=len)
                return Ques(a<<1,len);
            else if(x[a<<1].rs+x[a<<1|1].ls>=len)
                return mid-x[a<<1].rs+1;
            else
                return Ques(a<<1|1,len);
        }
        push_up(a);
    }
    int b_search(int a)
    {
        int l=0,r=z.size()-1;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(a<z[mid].l)
                r=mid-1;
            else
                l=mid+1;
        }
        return l;
    }
    int b_search1(int a)
    {
        int l=0,r=z.size()-1;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(z[mid].l<=a&&z[mid].r>=a)
                return mid;
            else if(z[mid].r<a)
                l=mid+1;
            else
                r=mid-1;
    
        }
        return -1;
    }
    
    void Update(int l,int r,int a1,int b1,int a) //变成都被占用
    {
        if(a1<=l&&r<=b1)
        {
            x[a].la=0;
            x[a].ls=x[a].rs=x[a].ms=0;
            return ;
        }
        if(x[a].la!=-1)
            push_down(a);
        int mid=(l+r)>>1;
        if(a1<=mid)
            Update(l,mid,a1,b1,a<<1);
        if(b1>mid)
            Update(mid+1,r,a1,b1,a<<1|1);
        push_up(a);
    }
    void Update1(int l,int r,int a1,int b1,int a)//变成都不被占用
    {
        if(a1<=l&&r<=b1)
        {
            x[a].la=1;
            x[a].ls=x[a].rs=x[a].ms=r-l+1;
            return ;
        }
        if(x[a].la!=-1)
            push_down(a);
        int mid=(l+r)>>1;
        if(a1<=mid)
            Update1(l,mid,a1,b1,a<<1);
        if(b1>mid)
            Update1(mid+1,r,a1,b1,a<<1|1);
        push_up(a);
    }
    int main()
    {
        while(scanf("%d%d",&n,&m) != EOF)
        {
            Build(1,n,1);
            z.clear();
            vector<no>::iterator it;
            no  p1;
            while(m--)
            {
                scanf("%s",s1);
                if(strcmp(s1,"New") == 0) //查询这段区间存不存在
                {
                    int a;
                    scanf("%d",&a);
                    int pos=Ques(1,a);
                    if(pos == 0)
                        printf("Reject New
    ");
                    else
                    {
                        printf("New at %d
    ",pos);
    
                        Update(1,n,pos,pos+a-1,1);  //更新
    
                        it=z.begin()+b_search(pos);
                        p1.l=pos;
                        p1.r=pos+a-1;
                        z.insert(it,p1);
                    }
                }
                else if(strcmp(s1,"Free") == 0)//二分 这个点有没有被使用
                {
                    int a;
                    scanf("%d",&a);
                    int pos=b_search1(a);
                    if(pos == -1)
                        printf("Reject Free
    ");
                    else
                    {
                        //
                        it = z.begin()+pos;
                        printf("Free from %d to %d
    ",it->l,it->r);
                        Update1(1,n,it->l,it->r,1);
                        z.erase(it);
                    }
                }
                else if(strcmp(s1,"Get") == 0)
                {
                    int a;
                    scanf("%d",&a);
                    if(z.size()<a)
                        printf("Reject Get
    ");
                    else
                        printf("Get at %d
    ",z[a-1].l);
                }
                else //全部都释放的话lazy一下
                {
                    x[1].la=1;
                    x[1].ls=x[1].rs=x[1].ms=n;
                    printf("Reset Now
    ");
                    z.clear();
                }
            }
            printf("
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    AtCoder Grand Contest 005F
    AtCoder Regular Contest 095E
    插头DP--URAL1519Formula 1
    「CodePlus 2018 3 月赛」白金元首与莫斯科
    hdu 5795
    hdu 5800
    HDU5802
    hdu 5787 数位dp,记忆化搜索
    poj 1015
    hdu 3092 (简化的素数打表+dp+log的用法) ps(开数组和预处理时数组要大点处理多一点。。。)
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6282006.html
Copyright © 2011-2022 走看看