传送门
线段树。同Hotel
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int max_n=5e5+5;
const int max_N=max_n*4;
int n,m,len,lrange,rrange,ans;
int sum[max_N],ls[max_N],rs[max_N],delta[max_N];
inline void update(int now,int l,int r,int mid){
if (ls[now<<1]==mid-l+1)
ls[now]=ls[now<<1]+ls[now<<1|1];
else
ls[now]=ls[now<<1];
if (rs[now<<1|1]==r-mid)
rs[now]=rs[now<<1|1]+rs[now<<1];
else
rs[now]=rs[now<<1|1];
sum[now]=max( ls[now] , rs[now] );
sum[now]=max( sum[now] , max( sum[now<<1] , sum[now<<1|1] ) );
sum[now]=max( sum[now] , rs[now<<1]+ls[now<<1|1] );
}
inline void pushdown(int now,int l,int r,int mid){
if (delta[now]!=-1){
if (!delta[now]){
sum[now<<1]=ls[now<<1]=rs[now<<1]=mid-l+1;
delta[now<<1]=delta[now];
sum[now<<1|1]=ls[now<<1|1]=rs[now<<1|1]=r-mid;
delta[now<<1|1]=delta[now];
}
else{
sum[now<<1]=ls[now<<1]=rs[now<<1]=0;
delta[now<<1]=delta[now];
sum[now<<1|1]=ls[now<<1|1]=rs[now<<1|1]=0;
delta[now<<1|1]=delta[now];
}
delta[now]=-1;
}
}
inline void build(int now,int l,int r){
// cout<<now<<endl;
int mid=(l+r)>>1;
if (l==r){
sum[now]=ls[now]=rs[now]=1;
return;
}
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
update(now,l,r,mid);
}
inline void interval_change(int now,int l,int r,int lrange,int rrange,int x){
int mid=(l+r)>>1;
if (lrange<=l&&r<=rrange){
if (!x)
sum[now]=ls[now]=rs[now]=r-l+1;
else
sum[now]=ls[now]=rs[now]=0;
delta[now]=x;
return;
}
pushdown(now,l,r,mid);
if (lrange<=mid)
interval_change(now<<1,l,mid,lrange,rrange,x);
if (mid+1<=rrange)
interval_change(now<<1|1,mid+1,r,lrange,rrange,x);
update(now,l,r,mid);
}
inline int find(int now,int l,int r,int len){
int mid=(l+r)>>1;
if (l==r) return l;
pushdown(now,l,r,mid);
if (sum[now<<1]>=len)
return find(now<<1,l,mid,len);
if (rs[now<<1]+ls[now<<1|1]>=len)
return mid-rs[now<<1]+1;
if (sum[now<<1|1]>=len)
return find(now<<1|1,mid+1,r,len);
}
int main(){
// freopen("seating.in","r",stdin);
// freopen("seating.out","w",stdout);
scanf("%d%d",&n,&m);
build(1,1,n);
memset(delta,-1,sizeof(delta));
for (int i=1;i<=m;++i){
char ch=getchar();
while (ch!='A'&&ch!='L') ch=getchar();
if (ch=='A'){
scanf("%d",&len);
if (sum[1]>=len){
int st=find(1,1,n,len);
interval_change(1,1,n,st,st+len-1,1);
}
else
ans++;
}
else{
scanf("%d%d",&lrange,&rrange);
if (lrange>rrange) swap(lrange,rrange);
interval_change(1,1,n,lrange,rrange,0);
}
}
printf("%d\n",ans);
return 0;
}
线段树不手残的重要性已经说过了,时刻牢记!
做过的题在考场上拿不了满分是一件可耻的事情。