POJ 3667 线段树+标记

自从某次考试写线段树写挂了以后 这是第一次写线段树,,,,,,

这是一个伤心的故事……
题意:
这里写图片描述
这里写图片描述

思路:
标记 维护从左到右的最大值 从右到左的最大值 区间内的最大值……

然后就一搞 就出来了

//By SiriusRen
#include <cstdio>
using namespace std;
int n,m,jy,xx,yy,d,D;
struct Tree{int lsum,rsum,sum,cover;}tree[222222];
inline int max(int x,int y){return x>y?x:y;}
inline int read(){
    int x=0;char p=getchar();
    while(p<'0'||p>'9')p=getchar();
    while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();
    return x;
}
void build(int l,int r,int pos){
    if(l==r){tree[pos].sum=tree[pos].lsum=tree[pos].rsum=1;return;}
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    build(l,mid,lson),build(mid+1,r,rson);
    tree[pos].lsum=tree[pos].rsum=tree[pos].sum=tree[lson].sum+tree[rson].sum;
}
void push_down(int num,int pos){
    int lson=pos<<1,rson=pos<<1|1;
    tree[lson].cover=tree[rson].cover=tree[pos].cover;
    if(tree[pos].cover==1){
        tree[lson].lsum=tree[lson].rsum=tree[lson].sum=num-(num>>1);
        tree[rson].lsum=tree[rson].rsum=tree[rson].sum=num>>1;
    }
    else{
        tree[lson].lsum=tree[lson].rsum=tree[lson].sum=0;
        tree[rson].lsum=tree[rson].rsum=tree[rson].sum=0;
    }
    tree[pos].cover=0;
}
void push_up(int num,int pos){
    int lson=pos<<1,rson=pos<<1|1,div=num>>1;
    tree[pos].lsum=tree[lson].lsum,tree[pos].rsum=tree[rson].rsum;
    tree[pos].sum=max(max(tree[lson].sum,tree[rson].sum),tree[lson].rsum+tree[rson].lsum);
    if(tree[lson].lsum==num-div)tree[pos].lsum+=tree[rson].lsum;
    if(tree[rson].rsum==div)tree[pos].rsum+=tree[lson].rsum;
}
int query(int l,int r,int pos){
    if(l==r)return l;
    if(tree[pos].cover)push_down(r-l+1,pos);
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    if(tree[pos].sum>=d){
        if(tree[lson].sum>=d)return query(l,mid,lson);
        if(tree[lson].rsum+tree[rson].lsum>=d)return mid+1-tree[lson].rsum;
        return query(mid+1,r,rson);
    }
    return 0;
}
void insert(int l,int r,int pos,int id){
    if(l>=xx&&r<=yy){
        tree[pos].cover=id;
        tree[pos].lsum=tree[pos].rsum=tree[pos].sum=(id==1?r-l+1:0);
        return;
    }
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1,len=r-l+1;
    if(tree[pos].cover)push_down(len,pos);
    if(mid<xx)insert(mid+1,r,rson,id);
    else if(mid>=yy)insert(l,mid,lson,id);
    else insert(l,mid,lson,id),insert(mid+1,r,rson,id);
    push_up(len,pos);
}
int main(){
    scanf("%d%d",&n,&m);
    build(1,n,1);
    for(int i=1;i<=m;i++){
        jy=read();
        if(jy==1){
            D=read(),d=D;
            xx=query(1,n,1),yy=xx+D-1;
            printf("%d
",xx);
            if(xx)insert(1,n,1,2);
        }
        else{
            xx=read(),yy=read();
            yy=xx+yy-1;
            insert(1,n,1,1);
        }
    }
}

这里写图片描述

原文地址:https://www.cnblogs.com/SiriusRen/p/6532285.html