P2894 [USACO08FEB] Hotel G [Line segment tree]

P2894 [USACO08FEB]Hotel G

Use 0 to represent space, 1 to represent
the node occupying the line segment tree to maintain the interval [ l , r ] [l,r] in this node[l,r ] The maximum number of consecutive 0s, the number of prefix 0s, and the number of suffix 0s.
Then recursively query when querying, first check whether the left node of the current node can meet the requirements, and return the answer directly, otherwise check whether the intermediate connection of the left and right nodes meets the requirements, and return if it is satisfied, otherwise return the answer of the right node

#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <iostream>
#include <map>
#include <cmath>
#include <set>

#define go(i, l, r) for(int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define god(i, r, l) for(int i = (r), i##end = (int)(l); i >= i##end; --i)
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define debug_in  freopen("in.txt","r",stdin)
#define debug_out freopen("out.txt","w",stdout);
#define pb push_back
#define all(x) x.begin(),x.end()
#define fs first
#define sc second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll maxM = 1e6+10;
const ll inf_int = 1e8;
const ll inf_ll = 1e17;

template<class T>void read(T &x){
    
    
    T s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    x = s*w;
}
template<class H, class... T> void read(H& h, T&... t) {
    
    
    read(h);
    read(t...);
}

void pt(){
    
     cout<<'\n';}
template<class H, class ... T> void pt(H h,T... t){
    
     cout<<" "<<h; pt(t...);}

//--------------------------------------------
const int maxn = 5e4 + 10;
int N,M;
struct Seg{
    
    
#define lson u<<1
#define rson u<<1|1
    struct node{
    
    
        int l,r;
        int len;
        int lz,rz;
        int tag;
    }tr[maxn * 4];
    void pushup(node &U,node &L,node &R){
    
    
        U.len = max(L.len,R.len);
        U.len = max(U.len,L.rz + R.lz);
        if(L.lz == L.r - L.l + 1) U.lz = L.lz + R.lz;
        else U.lz = L.lz;
        if(R.rz == R.r - R.l + 1) U.rz = L.rz + R.rz;
        else U.rz = R.rz;
    }
    void pushdown(node &U,node &L,node &R){
    
    
        if(U.tag != -1){
    
    
            if(U.tag == 1) {
    
    
                L.len = L.lz = L.rz = 0;
                R.len = R.lz = R.rz = 0;
            }else{
    
    
                L.len = L.lz = L.rz = L.r-L.l + 1;
                R.len = R.lz = R.rz = R.r-R.l + 1;
            }
            L.tag = U.tag;
            R.tag = U.tag;
            U.tag = -1;
        }
    }
    void build(int l,int r,int u){
    
    
        if(l == r) tr[u] = {
    
    l,r,1,1,1,-1};
        else{
    
    
            tr[u] = {
    
    l,r,0,0,0,-1};
            int mid = (l+r)>>1;
            build(l,mid,lson);
            build(mid+1,r,rson);
            pushup(tr[u],tr[lson],tr[rson]);
        }
    }
    void modify(int l,int r,int v,int u){
    
    
        if(l <= tr[u].l && tr[u].r <= r){
    
    
            if(v == 1) tr[u].len = tr[u].lz = tr[u].rz = 0;
            else tr[u].len = tr[u].lz = tr[u].rz = tr[u].r - tr[u].l + 1;
            tr[u].tag = v;
        }else{
    
    
            pushdown(tr[u],tr[lson],tr[rson]);
            int mid = (tr[u].l + tr[u].r)>>1;
            if(l<=mid) modify(l,r,v,lson);
            if(r>mid) modify(l,r,v,rson);
            pushup(tr[u],tr[lson],tr[rson]);
        }
    }
    int find(int v,int u){
    
    
        if(tr[u].len < v) return 0;
        if(tr[u].l == tr[u].r) return tr[u].l;
        int mid = (tr[u].l + tr[u].r)>>1;
        pushdown(tr[u],tr[lson],tr[rson]);
        int re1 = find(v,lson); if(re1) return re1;
        if(tr[lson].rz + tr[rson].lz >= v) return tr[lson].r - tr[lson].rz + 1;
        return find(v,rson);
    }
}seg;
int main() {
    
    
//    debug_in;
//    debug_out;

    cin>>N>>M;
    seg.build(1,N,1);
    for(int i = 1;i<=M;i++){
    
    
        int op;read(op);
        if(op == 1){
    
    
            int len;read(len);
            int id = seg.find(len,1);
            if(id){
    
    
                printf("%d\n",id);
                seg.modify(id,id+len-1,1,1);
            }else{
    
    
                puts("0");
            }
        }else{
    
    
            int l,len;read(l);read(len);
            seg.modify(l,l+len-1,0,1);
        }
    }

    return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326225040&siteId=291194637