zoukankan      html  css  js  c++  java
  • hdu2871线段树区间更新

    不得已又挖了一个坑。。想来学习线段树也有一段时间了,也有了些了解,但是在做题的

    时候还是磕磕碰碰的,还是不够熟练,还是要多做题(水题除外),多思考。

    这是一道典型的线段树区间更新,一定要使用延迟标记,同时又要使用区间合并。

    区间合并的做法和poj3667 Hotel这题是一样的。起先我想都使用线段树的查询,发现有困难

    然后参考了http://blog.csdn.net/azheng51714/article/details/8089260这里的做法,即保存分配

    过的区间的思路,因为所有的区间都是没有重合的,一个区间只能分配一次。但是无论我怎么

    改都是TLE。。有哪位大神可以帮我看看。。

    #include<cstdio>
    #include<algorithm>
    #include<map>
    #include<vector>
    using namespace std;
    const int maxn=50010;
    int llen[maxn*4],rlen[maxn*4],mlen[maxn*4];
    int change[maxn*4];
    struct seg{
        int l,r;
        seg(){}
        seg(int _l,int _r):l(_l),r(_r){}
        bool operator<(const seg &s)const
        {
            return l<s.l;
        }
    };
    vector<seg>sgmts;
    void pushUp(int root,int l,int r)
    {
        int len=r-l+1;
        llen[root]=llen[root*2];
        rlen[root]=rlen[root*2+1];
        if(llen[root*2]==len-len/2)llen[root]+=llen[root*2+1];
        if(rlen[root*2+1]==len/2)rlen[root]+=rlen[root*2];
        mlen[root]=max(rlen[root*2]+llen[root*2+1],max(mlen[root*2],mlen[root*2+1]));
    }
    void pushDown(int root,int l,int r)
    {
        if(change[root]!=-1){
            change[root*2]=change[root*2+1]=change[root];
            int t=change[root],len=r-l+1;
            llen[root*2]=rlen[root*2]=mlen[root*2]=t?0:len-len/2;//0表示释放,1表示分配
            llen[root*2+1]=rlen[root*2+1]=mlen[root*2+1]=t?0:len/2;
            change[root]=-1;
        }
    }
    void build(int root,int l,int r)
    {
        change[root]=-1;
        llen[root]=rlen[root]=mlen[root]=r-l+1;
        if(l==r)return;
        int mid=(l+r)/2;
        build(root*2,l,mid);
        build(root*2+1,mid+1,r);
    }
    void update(int root,int v,int L,int R,int l,int r)
    {
        if(R<l||L>r)return;
        if(L<=l&&r<=R){
            int len=r-l+1;
            change[root]=v;
            llen[root]=rlen[root]=mlen[root]=v?0:len;//0表示释放,1表示分配///
            return;
        }
        pushDown(root,l,r);
        int mid=(l+r)/2;
        if(mid>=L)update(root*2,v,L,R,l,mid);
        if(mid<R)update(root*2+1,v,L,R,mid+1,r);
        pushUp(root,l,r);
    }
    int query2(int root,int w,int l,int r)
    {
        if(l==r)return l;///
        pushDown(root,l,r);
        int mid=(l+r)/2;
        if(mlen[root*2]>=w)return query2(root*2,w,l,mid);
        else if(rlen[root*2]+llen[root*2+1]>=w)return mid-rlen[root*2]+1;
        else return query2(root*2+1,w,mid+1,r);
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int N,M;
        while(scanf("%d%d
    ",&N,&M)!=EOF){
            char cmd[10];
            int n;
            build(1,1,N);
            sgmts.clear();
            while(M--){
                scanf("%s",cmd);
                if(cmd[0]=='N'){
                    scanf("%d",&n);
                    if(mlen[1]<n)printf("Reject New
    ");
                    else {
                        int p=query2(1,n,1,N);
                        update(1,1,p,p+n-1,1,N);
                        //sgmts.push_back(seg(p,p+n-1));
                        //sort(sgmts.begin(),sgmts.end());
                        seg t=seg(p,p+n-1);
                        auto itr=upper_bound(sgmts.begin(),sgmts.end(),t);
                        sgmts.insert(itr,t);
                        printf("New at %d
    ",p);
                    }
                }
                if(cmd[0]=='F'){
                    scanf("%d",&n);
                    seg t=seg(n,n);
                    auto p=upper_bound(sgmts.begin(),sgmts.end(),t);
                    if(p==sgmts.begin()||(--p)->r<n)printf("Reject Free
    ");
                    else {
                        update(1,0,p->l,p->r,1,N);
                        printf("Free from %d to %d
    ",p->l,p->r);
                        sgmts.erase(p);
                    }
                }
                if(cmd[0]=='G'){
                    scanf("%d",&n);
                    if(n>sgmts.size())printf("Reject Get
    ");
                    else{
                        printf("Get at %d
    ",sgmts[n-1].l);
                    }
                }
                if(cmd[0]=='R'){
                    //build(1,1,N);//
                    update(1,0,1,N,1,N);
                    sgmts.clear();
                    printf("Reset Now
    ");
                }
            }
            printf("
    ");
        }
        //while(1);
    }
  • 相关阅读:
    让你的网站(MAXCMS4_0)按地区、年份、语言生成分页面(已经修正)
    IPTV
    超简单,MAX普通版改为资源版方法
    Jmter操作数据库
    JMter中添加断点和关联
    jmeter返回报文乱码问题
    Jmter安装和配置
    JMter压力测试
    今天注册了
    不能登陆后删除Cookies解决
  • 原文地址:https://www.cnblogs.com/MalcolmMeng/p/8449505.html
Copyright © 2011-2022 走看看