标记线段树的时候利用 lsum rsum msum 记录最左边 zui右边 以及整个区间的最大连续空位的值
维护的时候注意合并
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define lson (pos<<1) #define rson (pos<<1|1) const int maxn = 55555; int n,m; struct Node{ int l,r,lsum,rsum,msum,col; int len(){ return r - l + 1; } int mid(){ return (l + r) >> 1; } }node[maxn << 2]; void build(int l,int r,int pos){ node[pos].l = l; node[pos].r = r; node[pos].col = -1; node[pos].lsum = node[pos].rsum = node[pos].msum = node[pos].len(); if(l == r) return; int mid = node[pos].mid(); build(l,mid,lson); build(mid + 1,r,rson); } void pushdown(int pos){ if(node[pos].col != -1){ if(!node[pos].col){ node[lson].lsum = node[lson].rsum = node[lson].msum = 0; node[rson].lsum = node[rson].rsum = node[rson].msum = 0; node[lson].col = node[rson].col = 0; } else{ node[lson].lsum = node[lson].rsum = node[lson].msum = node[lson].len(); node[rson].lsum = node[rson].rsum = node[rson].msum = node[rson].len(); node[lson].col = node[rson].col = 1; } node[pos].col = -1; } } void pushup(int pos){ node[pos].lsum = node[lson].lsum; node[pos].rsum = node[rson].rsum; if(node[lson].lsum == node[lson].len()) node[pos].lsum += node[rson].lsum; if(node[rson].rsum == node[rson].len()) node[pos].rsum += node[lson].rsum; node[pos].msum = node[lson].rsum + node[rson].lsum; node[pos].msum = max(node[pos].msum,max(node[lson].msum,node[rson].msum)); } void update(int l,int r,int pos,int d){ if(l <= node[pos].l && node[pos].r <= r){ if(d == 1){ node[pos].lsum = node[pos].rsum = node[pos].msum = node[pos].len(); node[pos].col = 1; } if(d == 0){ node[pos].lsum = node[pos].rsum = node[pos].msum = 0; node[pos].col = 0; } return; } pushdown(pos); int mid = node[pos].mid(); if(l <= mid) update(l,r,lson,d); if(r > mid) update(l,r,rson,d); pushup(pos); } int query(int l,int r,int pos,int v){ if(l == r) return l; pushdown(pos); if(node[lson].msum >= v) return query(l,r,lson,v); else if(node[lson].rsum + node[rson].lsum >= v) return node[pos].mid() - node[lson].rsum + 1; return query(l,r,rson,v); } int main(){ while(scanf("%d%d",&n,&m) != EOF){ build(1,n,1); for(int i = 0; i < m; i++){ int op,l,r; scanf("%d",&op); if(op == 1){ scanf("%d",&l); if(node[1].msum < l) printf("0\n"); else{ int v = query(1,n,1,l); printf("%d\n",v); update(v,v + l - 1,1,0); //printf("%d\n",node[1].msum); } } else{ scanf("%d%d",&l,&r); update(l,l + r - 1,1,1); } } } return 0; }
时间: 2024-10-15 07:01:00