很最近的div3 H 很像

单点变成区间修改了
多一个懒标记就可以了,但是维护范围是1,n,div3 H 是无限值域来找最小位置
找到的条件是seg[1].tmx>=v 否则就是0
// Problem: P2894 [USACO08FEB] Hotel G
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2894
// Memory Limit: 128 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#define INF (1<<30)
using namespace std;
typedef long long ll;
const int N=1e5+9;
struct SEG{
struct node{
int l,r,len;
int tag;
ll lmx,rmx,tmx;
}seg[N<<2];
#define tl(id) id<<1
#define tr(id) id<<1|1
#define li inline
li void pushup(node &id,node &l,node &r){
id.lmx=l.lmx+r.lmx*(l.lmx==l.len);
id.rmx=r.rmx+l.rmx*(r.rmx==r.len);
id.tmx=max(l.tmx,max(r.tmx,l.rmx+r.lmx));
}
#define pushup(id) pushup(seg[id],seg[tl(id)],seg[tr(id)])
li void build(int id,int l,int r){
seg[id]={l,r,r-l+1,INF};
if(l==r){
seg[id]={l,r,r-l+1,INF,1,1,1};
return;
}
int mid=(l+r)>>1;
build(tl(id),l,mid);
build(tr(id),mid+1,r);
pushup(id);
}
li int inrange(int L,int R,int l,int r){return L>=l && R<=r;}
li int outofrange(int L,int R,int l,int r){return L>r || l>R;}
li void maketag(int id,int l,int r,int v){
seg[id].tag=v;
seg[id].lmx=seg[id].rmx=seg[id].tmx=(r-l+1)*(!v);//!v 0->1 ,1->0
}
li void pushdown(int id,int l,int r){
if(seg[id].tag==INF){
return;
}
int mid=(l+r)>>1;
maketag(tl(id),l,mid,seg[id].tag);
maketag(tr(id),mid+1,r,seg[id].tag);
seg[id].tag=INF;
}
li void modify(int id,int l,int r,int v){
if(inrange(seg[id].l,seg[id].r,l,r)){
maketag(id,seg[id].l,seg[id].r,v);//
}else if(!outofrange(seg[id].l,seg[id].r,l,r)){
pushdown(id,seg[id].l,seg[id].r);
modify(tl(id),l,r,v);
modify(tr(id),l,r,v);
pushup(id);
}
}
li ll query(int id,int l,int r,int v){
if(l==r){
return l;
}
int mid=(l+r)>>1;
pushdown(id,l,r);
if(seg[tl(id)].tmx>=v){
return query(tl(id),l,mid,v);
}
if(seg[tl(id)].rmx+seg[tr(id)].lmx>=v){
return seg[tl(id)].r-seg[tl(id)].rmx+1;
}
if(seg[tr(id)].tmx>=v){
return query(tr(id),mid+1,r,v);
}
return 0;
}
}t;
int main(){
int n,m;
cin>>n>>m;
t.build(1,1,n);
for(int i=1;i<=m;i++){
int op;
cin>>op;
if(op==1){
int x;
cin>>x;
if(t.seg[1].tmx<x){
cout<<0<<'\n';
continue;
}
ll tt=t.query(1,1,n,x);
cout<<tt<<'\n';
t.modify(1,tt,tt+x-1,1);
}else{
int x,y;
cin>>x>>y;
t.modify(1,x,x+y-1,0);
}
}
}
368

被折叠的 条评论
为什么被折叠?



