为什么没有题解?似乎讨论版里的也是错的=_= ......
这样的话我就来写一篇吧lalal(`・ω・´)
我有点怀疑标签,毕竟谁能想出这个怎么用(单调)队列写???
懵逼
其实我是用线段树写的。
每个节点(区间)记录三个变量:
sl[i]:从左往右有连续多少个空位
sr[i]:从右往左有连续多少个空位
s[i]:这个区间中最长连续多少个空位
1 //ln指左孩子的区间包含多少座位 2 //rn指右孩子的区间包含多少座位 3 //rt指当前节点 4 5 向上更新: 6 7 inline void pu(int rt,int ln,int rn){ 8 s[rt]=max(max(s[ls],s[rs]),sr[ls]+sl[rs]); 9 sl[rt]=sl[ls]+(sl[ls]==ln)*sl[rs]; 10 sr[rt]=sr[rs]+(sr[rs]==rn)*sr[ls]; 11 } 12 13 向下更新: 14 //add指懒惰标记 15 inline void pd(int rt,int ln,int rn){ 16 if(!add[rt]||(!ln&&!rn))return; 17 s[ls]=sl[ls]=sr[ls]=(add[rt]>0)*ln; 18 s[rs]=sl[rs]=sr[rs]=(add[rt]>0)*rn; 19 add[ls]=add[rs]=add[rt];add[rt]=0; 20 }
相信大家看代码应该是能看得懂的>_<
那么我就来给完整代码了:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 namespace ZDY{ 3 #define ll long long 4 #define Fur(i,x,y) for(int i=x;i<=y;i++) 5 #define in2(x,y) in(x);in(y) 6 }using namespace ZDY;using namespace std; 7 #define N 5000011 8 #define ls rt<<1 9 #define rs ls|1 10 #define Z int m=(l+r)>>1 11 #define lson l,m,ls 12 #define rson m+1,r,rs 13 ll s[N<<2],sl[N<<2],sr[N<<2]; 14 int n,q; 15 short add[N]; 16 inline void pu(int rt,int ln,int rn){ 17 s[rt]=max(max(s[ls],s[rs]),sr[ls]+sl[rs]); 18 sl[rt]=sl[ls]+(sl[ls]==ln)*sl[rs]; 19 sr[rt]=sr[rs]+(sr[rs]==rn)*sr[ls]; 20 } 21 inline void pd(int rt,int ln,int rn){ 22 if(!add[rt]||(!ln&&!rn))return; 23 s[ls]=sl[ls]=sr[ls]=(add[rt]>0)*ln; 24 s[rs]=sl[rs]=sr[rs]=(add[rt]>0)*rn; 25 add[ls]=add[rs]=add[rt];add[rt]=0; 26 } 27 inline void build(int l,int r,int rt){ 28 s[rt]=sl[rt]=sr[rt]=r-l+1;if(l==r)return; 29 Z;build(lson);build(rson); 30 } 31 inline void upd(int L,int R,int l,int r,int rt,int v){ 32 if(L<=l&&r<=R){s[rt]=sl[rt]=sr[rt]=(v>0)*(r-l+1),add[rt]=v;return;} 33 Z;pd(rt,m-l+1,r-m); 34 if(L<=m)upd(L,R,lson,v); 35 if(R>m)upd(L,R,rson,v); 36 pu(rt,m-l+1,r-m); 37 } 38 inline int ask(int c,int l,int r,int rt){ 39 Z;pd(rt,m-l+1,r-m); 40 if(s[ls]>=c)return ask(c,lson); 41 else if(sr[ls]+sl[rs]>=c)return m-sr[ls]+1; 42 else return ask(c,rson); 43 } 44 int main(){ 45 scanf("%d%d",&n,&q);build(1,n,1); 46 int x,y,ans=0,pos; 47 while(q--) 48 if(sc()=='A'){ 49 scanf("%d",&x); 50 if(s[1]<x)ans++; 51 else{ 52 pos=ask(x,1,n,1); 53 upd(pos,pos+x-1,1,n,1,-1); 54 } 55 } 56 else{scanf("%d%d",&x,&y);upd(x,y,1,n,1,1);} 57 cout<<ans<<endl; 58 }
好像这题和P2894 [USACO08FEB]酒店Hotel 重复了...