1. 程式人生 > >luogu2894 [USACO08FEB]酒店Hotel

luogu2894 [USACO08FEB]酒店Hotel

ould 線段樹求區間最值 build 線段樹 names uil ans div mark

跟線段樹求區間最值一樣每個節點維護左邊開始的最大連續空房間數、右邊開始的最大連續空房間數、這個區間內的最大連續空房間數

#include <iostream>
#include <cstdio>
using namespace std;
int n, m, opt, uu, vv;
struct SGT{
    int lma[200005], rma[200005], sum[200005], tag[200005];
    //sum means there are how many empty rooms
    //tag==2 means these room should be clear, 1 means not
void pushUp(int o, int l, int r, int lson, int rson, int mid){ if(sum[lson]==mid-l+1) lma[o] = mid - l + 1 + lma[rson]; else lma[o] = lma[lson]; if(sum[rson]==r-mid) rma[o] = r - mid + rma[lson]; else rma[o] = rma[rson]; sum[o] = max(rma[lson] + lma[rson], max(sum[lson], sum[rson])); } void
pushDown(int o, int l, int r, int lson, int rson, int mid){ tag[lson] = tag[rson] = tag[o]; sum[lson] = lma[lson] = rma[lson] = (mid - l + 1) * (tag[o] - 1); sum[rson] = lma[rson] = rma[rson] = (r - mid) * (tag[o] - 1); tag[o] = 0; } void build(int o, int l, int
r){ if(l==r) lma[o] = rma[o] = sum[o] = 1; else{ int mid=(l+r)>>1; int lson=o<<1; int rson=lson|1; if(l<=mid) build(lson, l, mid); if(mid<r) build(rson, mid+1, r); pushUp(o, l, r, lson, rson, mid); } } int query(int o, int l, int r, int x){ if(l==r) return l; else{ int mid=(l+r)>>1; int lson=o<<1; int rson=lson|1; if(tag[o]) pushDown(o, l, r, lson, rson, mid); if(sum[lson]>=x) return query(lson, l, mid, x); else if(rma[lson]+lma[rson]>=x) return mid-rma[lson]+1; else return query(rson, mid+1, r, x); } } void modify(int o, int l, int r, int x, int y, int k){ if(l>=x && r<=y){ sum[o] = lma[o] = rma[o] = (r - l + 1) * (k - 1); tag[o] = k; } else{ int mid=(l+r)>>1; int lson=o<<1; int rson=lson|1; if(tag[o]) pushDown(o, l, r, lson, rson, mid); if(x<=mid) modify(lson, l, mid, x, y, k); if(mid<y) modify(rson, mid+1, r, x, y, k); pushUp(o, l, r, lson, rson, mid); } } }sgt; int main(){ cin>>n>>m; sgt.build(1, 1, n); while(m--){ scanf("%d", &opt); if(opt==1){ scanf("%d", &uu); if(sgt.sum[1]<uu) printf("0\n"); else{ int ans=sgt.query(1, 1, n, uu); printf("%d\n", ans); sgt.modify(1, 1, n, ans, ans+uu-1, 1); } } else{ scanf("%d %d", &uu, &vv); sgt.modify(1, 1, n, uu, uu+vv-1, 2); } } return 0; }

luogu2894 [USACO08FEB]酒店Hotel