261. 旅馆

题目链接:https://www.acwing.com/problem/content/263/

思路:跟 线段树维护区间最大连续区间的类似思路  ld为前缀最长连续1 rd为后缀最长连续1

d为当前区间内最长连续的1  注意的点就是

1.多了一个区间修改 注意传lazy

2.只有当左区间满了1 才能将ld 加上右区间的贡献  就是pushup时ld rd的更新

3.query的时候注意 只有当前区间需要左右两个区间我们才能定下来开始的端点位置

否则的话 左区间满足就往左区间走

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 #define pi pair<int,int>
  5 #define pb push_back
  6 #define fi first
  7 #define sc second
  8 #define ull unsigned long long
  9 const int maxn=5e4+10;
 10 const int mod=1e9+7;
 11 
 12 
 13 struct ac
 14 {
 15     int l,r;
 16     int d,ld,rd;
 17     int lazy;// lazy 将整个区间置为同一个数
 18     void update(int v)
 19     {
 20         d=ld=rd=(r-l+1)*v;
 21         lazy=v;
 22     }
 23 };
 24 ac tr[maxn*4];
 25 
 26 
 27 void pushup(ac &u,ac &l,ac &r)
 28 {
 29     u.ld=l.ld;
 30     if(l.d==l.r-l.l+1) u.ld=l.d+r.ld;
 31     u.rd=r.rd;
 32     if(r.d==r.r-r.l+1) u.rd=r.d+l.rd;
 33     u.d=max({l.d,r.d,l.rd+r.ld});
 34 }
 35 
 36 void pushup(int x)
 37 {
 38     pushup(tr[x],tr[x<<1],tr[x<<1|1]);
 39 }
 40 
 41 void build(int x,int l,int r)
 42 {
 43     tr[x]={l,r,1,1,1,-1};
 44     if(l==r) return;
 45     int mid=l+r>>1;
 46     build(x<<1,l,mid);
 47     build(x<<1|1,mid+1,r);
 48     pushup(x);
 49 }
 50 
 51 void pushdown(ac &u,ac &l,ac &r)
 52 {
 53     int v=u.lazy;
 54     if(v!=-1)
 55     {
 56         l.update(v);
 57         r.update(v);
 58         u.lazy=-1;
 59     }
 60 }
 61 
 62 void pushdown(int x)
 63 {
 64     int v=tr[x].lazy;
 65     if(v!=-1) pushdown(tr[x],tr[x<<1],tr[x<<1|1]);
 66 }
 67 
 68 
 69 void update(int x,int l,int r,int v)
 70 {
 71     int L=tr[x].l,R=tr[x].r;
 72     if(l<=L&&R<=r)
 73     {
 74         tr[x].update(v);
 75         return;
 76     }
 77     int mid=L+R>>1;
 78     pushdown(x);
 79     if(l<=mid) update(x<<1,l,r,v);
 80     if(r>mid) update(x<<1|1,l,r,v);
 81     pushup(x);
 82 }
 83 
 84 int query(int x,int v)
 85 {
 86     //nan
 87     if(tr[x].d<v) return 0;
 88     pushdown(x);
 89     if(tr[x<<1].d>=v) return query(x<<1,v);
 90     if(tr[x<<1].rd+tr[x<<1|1].ld>=v) return tr[x<<1].r-tr[x<<1].rd+1;
 91     if(tr[x<<1|1].d>=v) return query(x<<1|1,v);
 92 }
 93 
 94 
 95 
 96 int main()
 97 {
 98     ios::sync_with_stdio(0);
 99     cin.tie(0);
100     int n,m;
101     cin>>n>>m;
102     build(1,1,n);
103     while(m--)
104     {
105         int op;
106         cin>>op;
107         if(op==1)
108         {
109             int x;
110             cin>>x;
111             int p=query(1,x);
112             if(p) update(1,p,p+x-1,0);
113             cout<<p<<'\n';
114         }
115         else
116         {
117             int x,v;
118             cin>>x>>v;
119             update(1,x,x+v-1,1);
120         }
121     }
122 
123 
124 
125 
126 
127 }
View Code

 

posted @ 2021-04-25 16:08  canwinfor  阅读(46)  评论(0编辑  收藏  举报