记录编号 |
582728 |
评测结果 |
AAAAAAAAAAAA |
题目名称 |
[USACO Feb08] 旅馆 |
最终得分 |
100 |
用户昵称 |
┭┮﹏┭┮ |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.187 s |
提交时间 |
2023-09-23 16:46:29 |
内存使用 |
0.00 MiB |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5+10;
int n,m;
struct made{
int l,r;
int lm,rm,s,sum;//从左连续房间数 从右连续房间数 区间内最大连续数 区间总数
int dat;//延迟标记
#define l(x) t[x].l
#define r(x) t[x].r
#define lm(x) t[x].lm
#define rm(x) t[x].rm
#define s(x) t[x].s
#define dat(x) t[x].dat
#define sum(x) t[x].sum
}t[N<<2];
void pushup(int x){
if(dat(x) == 1)lm(x) = rm(x) = s(x) = r(x) - l(x) + 1;
else if(l(x) == r(x) || dat(x) == 0)lm(x) = rm(x) = s(x) = 0;
else{
if(lm(x<<1) == sum(x<<1))lm(x) = lm(x<<1) + lm(x<<1|1);
else lm(x) = lm(x<<1);
if(rm(x<<1|1) == sum(x<<1|1))rm(x) = rm(x<<1|1) + rm(x<<1);
else rm(x) = rm(x<<1|1);
s(x) = max(s(x<<1),max(s(x<<1|1),rm(x<<1)+lm(x<<1|1)));
}//上传
}
void pushdown(int x){
if(dat(x) == 1){
dat(x<<1) = dat(x<<1|1) = dat(x);
lm(x<<1) = rm(x<<1) = s(x<<1) = r(x<<1) - l(x<<1) + 1;
lm(x<<1|1) = rm(x<<1|1) = s(x<<1|1) = r(x<<1|1) - l(x<<1|1) + 1;
}
else if(dat(x) == 0){
dat(x<<1) = dat(x<<1|1) = dat(x);
lm(x<<1) = rm(x<<1) = s(x<<1) = 0;
lm(x<<1|1) = rm(x<<1|1) = s(x<<1|1) = 0;
}//延迟标记下传
dat(x) = -1;
}
void build(int x,int l,int r){
l(x) = l,r(x) = r,dat(x) = 1;
sum(x) = r-l+1;
if(l == r){
pushup(x);
return;
}
int mid = l + r >> 1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}//建树初始化
int ask(int x,int l,int r,int z){
if(s(x) < z)return 0;
pushdown(x);//下传延迟标记
int mid = l + r >> 1;
if(s(x<<1) >= z)return ask(x<<1,l,mid,z);//左边
else if(rm(x<<1) + lm(x<<1|1) >= z)return mid - rm(x<<1) + 1;//中间
else return ask(x<<1|1,mid+1,r,z) ;//右边
}
void add(int x,int l,int r,int z){
if(l <= l(x) && r(x) <= r){
dat(x) = z;
if(z == 1)lm(x) = rm(x) = s(x) = r(x) - l(x) + 1;
else lm(x) = rm(x) = s(x) = 0;//延迟标记
pushdown(x);
return;
}
pushdown(x);
int mid = l(x) + r(x) >> 1;
if(mid >= l)add(x<<1,l,r,z);
if(mid < r)add(x<<1|1,l,r,z);
pushup(x);
}
int main(){
freopen("usaco_feb08_hotel.in","r",stdin);
freopen("usaco_feb08_hotel.out","w",stdout);
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i = 1;i <= m;i++){
int x,y,z;
scanf("%d%d",&x,&y);
if(x == 1){
int ans = ask(1,1,n,y);
printf("%d\n",ans);
if(ans)add(1,ans,ans+y-1,0);//0为被占房间
}
else{
scanf("%d",&z);
add(1,y,y+z-1,1);//1为空房间
}
}
return 0;
}