• hdu4553 两棵线段树


    hdu4553 约会安排
    传送门
    题意
    一个人有长度为(n)的空闲时间,有三种操作:
    1.基友来约长度为(t)的空闲时间,判断是否可行,如果可行计算开始时间最早的时刻
    2.女神来约长度为(t)的空闲时间,首先判断在不耽误和之前基友约会的情况下是否可行,如果不可行,再判断在取消和某些基友约会的情况下是否可行,计算两种情况下可行时开始时间最早的时刻
    3.立志好好学习,清空区间([l,r])之内的所有约会
    题解
    为基友和女神建立两棵线段树
    (1)表示时间点空闲,(0)表示时间点被占用
    三种操作的对应处理方式:
    1.基友的请求只在基友线段树上找,找到之后更新也只更新基友线段树
    2.女神的请求先在基友线段树上找,如果找不到再在女神线段树上找,不管在哪棵线段树上找到长度为(t)的空闲时间,都需要更新两棵线段树的对应区间,因为女神的优先级高于基友,如果一个区间被女神占了,那么既不能被基友占也不能被其他女神占
    3.同时清空基友线段树和女神线段树的相应区间
    (ps:)线段树区间更新需要设立(lazy)标记,但是(lazy)不能初始化成(0),因为之前已经设定(0)表示被占用。可以将(lazy)初始化成(-1),这样清除时也将(lazy)更改为(-1)

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<set>
    #include<map>
    #include<cstring>
    #include<string>
    #include<sstream>
    #include<cmath>
    #include<ctime>
    #include<climits>
    #include<algorithm>
    #define LL long long
    #define PII pair<int,int>
    #define PLL pair<LL,LL>
    #define pi acos(-1.0)
    #define eps 1e-6
    #define lowbit(x) x&(-x)
    using namespace std;
    
    const int maxn=110010;
    int T,n,m;
    char s[10];
    struct node{
        int lmx,rmx,amx,lazy;
    }ds[4*maxn],ns[4*maxn];
    
    void pushup(node* tree,int o,int l,int r){
        int mid=(l+r)>>1;
        tree[o].lmx=tree[o<<1].lmx;
        if(tree[o<<1].lmx==mid-l+1) tree[o].lmx+=tree[o<<1|1].lmx;
        tree[o].rmx=tree[o<<1|1].rmx;
        if(tree[o<<1|1].rmx==r-mid) tree[o].rmx+=tree[o<<1].rmx;
        tree[o].amx=max(max(tree[o<<1].amx,tree[o<<1|1].amx),tree[o<<1].rmx+tree[o<<1|1].lmx);
    }
    
    void build(node* tree,int o,int l,int r){
        tree[o].lazy=-1;
        if(l==r){
            tree[o].lmx=tree[o].rmx=tree[o].amx=1;
            return;
        }
        int mid=(l+r)>>1;
        build(tree,o<<1,l,mid);
        build(tree,o<<1|1,mid+1,r);
        pushup(tree,o,l,r);
    }
    
    void puttag(node* tree,int o,int l,int r,int v){
        tree[o].lazy=v;
        tree[o].lmx=tree[o].rmx=tree[o].amx=v*(r-l+1);
    }
    
    void pushdown(node* tree,int o,int l,int r){
        if(tree[o].lazy==-1) return;
        int mid=(l+r)>>1;
        tree[o<<1].lazy=tree[o].lazy;
        tree[o<<1|1].lazy=tree[o].lazy;
        tree[o].lazy=-1;
        tree[o<<1].lmx=tree[o<<1].rmx=tree[o<<1].amx=tree[o<<1].lazy*(mid-l+1);
        tree[o<<1|1].lmx=tree[o<<1|1].rmx=tree[o<<1|1].amx=tree[o<<1|1].lazy*(r-mid);
    }
    
    void change(node* tree,int o,int l,int r,int ql,int qr,int v){
        if(ql<=l && r<=qr){
            puttag(tree,o,l,r,v);
            return;
        }
        pushdown(tree,o,l,r);
        int mid=(l+r)>>1;
        if(ql<=mid) change(tree,o<<1,l,mid,ql,qr,v);
        if(qr>mid) change(tree,o<<1|1,mid+1,r,ql,qr,v);
        pushup(tree,o,l,r);
    }
    
    int query(node* tree,int o,int l,int r,int len){
        if(tree[o].amx<len) return 0;
        if(l==r) return l;
        pushdown(tree,o,l,r);
        int mid=(l+r)>>1;
        if(tree[o<<1].amx>=len) return query(tree,o<<1,l,mid,len);
        if(tree[o<<1].rmx+tree[o<<1|1].lmx>=len) return mid-tree[o<<1].rmx+1;
        return query(tree,o<<1|1,mid+1,r,len);
    }
    
    int main(){
        scanf("%d",&T);
        for(int cas=1;cas<=T;cas++){
            printf("Case %d:
    ",cas);
            scanf("%d %d",&n,&m);
            build(ds,1,1,n);
            build(ns,1,1,n);
            while(m--){
                scanf("%s",s);
                if(s[0]=='D'){
                    int t,x=0;
                    scanf("%d",&t);
                    x=query(ds,1,1,n,t);
                    if(x){
                        printf("%d,let's fly
    ",x);
                        change(ds,1,1,n,x,x+t-1,0);
                    }
                    else printf("fly with yourself
    ");
                }
                else if(s[0]=='N'){
                    int t,x=0;
                    scanf("%d",&t);
                    x=query(ds,1,1,n,t);
                    if(x){
                        change(ds,1,1,n,x,x+t-1,0);
                        change(ns,1,1,n,x,x+t-1,0);
                    }
                    else{
                        x=query(ns,1,1,n,t);
                        if(x){
                            change(ns,1,1,n,x,x+t-1,0);
                            change(ds,1,1,n,x,x+t-1,0);
                        }
                    }
                    if(x) printf("%d,don't put my gezi
    ",x);
                    else printf("wait for me
    ");
                }
                else{
                    int l,r;
                    scanf("%d %d",&l,&r);
                    change(ds,1,1,n,l,r,1);
                    change(ns,1,1,n,l,r,1);
                    printf("I am the hope of chinese chengxuyuan!!
    ");
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    js键盘按钮keyCode及示例大全
    HTML 禁止复制文字
    【Layui】formSelects下拉多选框取值
    JQuery 判断访问的浏览器是pc还是手机
    php发送post请求的方法
    用PHP实现小写金额转换大写金额【精确到分】
    PHP获取文件大小的几种方法!
    js jquery 数组的合并 对象的合并
    web页面长时间未操作自动退出登录
    获取公众号素材管理列表-教程
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13566149.html
Copyright © 2020-2023  润新知