zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    日志文件压缩
    Exchange2010 部署
    预读取页面 Prefetching pages
    利用Response的WriteFile方法输出一些文件
    事务记录工作中遇到的问题
    Orchard源码分析(7.1):Routing(路由)相关
    关于挑库规则的问题
    Oracle认证考试:EBS模块中文名称及英文缩写
    Oracle EBS 实施方法论扫盲:都有哪些实施方法论
    [二次开发] EBS R12 探索之路【EBS 经典SQL分享】
  • 原文地址:https://www.cnblogs.com/harden/p/6395594.html
Copyright © 2011-2022 走看看