• Hotel(poj 3667)


    题意:询问区间最长连续空串 

    /*
      用线段树维护区间最长连续左空串和右空串 
    */
    #include<cstdio>
    #include<iostream>
    #define N 50010
    using namespace std;
    int sum[N*4],lsum[N*4],rsum[N*4],cover[N*4],n,m;
    void push_up(int k,int l,int r){
        int mid=l+r>>1;
        sum[k]=max(max(sum[k*2],sum[k*2+1]),rsum[k*2]+lsum[k*2+1]);
        lsum[k]=lsum[k*2];
        if(lsum[k*2]==mid-l+1) lsum[k]+=lsum[k*2+1];
        rsum[k]=rsum[k*2+1];
        if(rsum[k*2+1]==r-mid) rsum[k]+=rsum[k*2];
    }
    void push_down(int k,int l,int r){
        if(!cover[k]) return;
        int mid=l+r>>1;
        if(cover[k]==-1){
            lsum[k*2]=rsum[k*2]=sum[k*2]=0;
            lsum[k*2+1]=rsum[k*2+1]=sum[k*2+1]=0;
            cover[k*2]=cover[k*2+1]=-1;
        }
        else {
            lsum[k*2]=rsum[k*2]=sum[k*2]=mid-l+1;
            lsum[k*2+1]=rsum[k*2+1]=sum[k*2+1]=r-mid;
            cover[k*2]=cover[k*2+1]=1;
        }
        cover[k]=0;
    }
    void build(int l,int r,int k){
        if(l==r){
            cover[k]=0;
            lsum[k]=rsum[k]=sum[k]=1;
            return;
        }
        int mid=l+r>>1;
        build(l,mid,k*2);
        build(mid+1,r,k*2+1);
        push_up(k,l,r);
    }
    int query(int l,int r,int k,int x){
        if(l==r)return l;
        push_down(k,l,r);
        int mid=l+r>>1;
        if(sum[k*2]>=x)return query(l,mid,k*2,x);
        else if(rsum[k*2]+lsum[k*2+1]>=x) return mid-rsum[k*2]+1;
        else return query(mid+1,r,k*2+1,x);
    }
    void change(int l,int r,int k,int c,int x,int y){
        if(l>=x&&r<=y){
            cover[k]=c;
            lsum[k]=rsum[k]=sum[k]=c==-1?0:r-l+1;
            return;
        }
        push_down(k,l,r);
        int mid=l+r>>1;
        if(x<=mid) change(l,mid,k*2,c,x,y);
        if(y>mid) change(mid+1,r,k*2+1,c,x,y);
        push_up(k,l,r);
    }
    int main(){
        scanf("%d%d",&n,&m);
        build(1,n,1);
        for(int i=1;i<=m;i++){
            int opt,x,y;scanf("%d",&opt);
            if(opt==1){
                scanf("%d",&x);
                if(sum[1]<x){
                    printf("0
    ");
                    continue;
                }
                int p=query(1,n,1,x);
                printf("%d
    ",p);
                change(1,n,1,-1,p,p+x-1);
            }
            else {
                scanf("%d%d",&x,&y);
                change(1,n,1,1,x,x+y-1);
            }
        }
        return 0;
    }
  • 相关阅读:
    Java 快速入门-06-JDK 目录文件说明
    Java快速入门-05-数组循环条件 实例《延禧攻略》
    腾讯云服务器 选购+远程控制 图文教程
    无法获得锁 /var/lib/dpkg/lock
    Ubuntu 安装 PhpMyAdmin 图文教程
    基于Redis的BloomFilter算法去重
    CAP理论
    Linux常用命令回顾
    基于Solr实现HBase的二级索引
    Solr搜索服务架构图
  • 原文地址:https://www.cnblogs.com/harden/p/6395594.html
Copyright © 2020-2023  润新知