约会安排 (连续区间 + lazy优先级)

题目链接:https://vjudge.net/contest/332656#problem/I

题目大意:

小明需要安排和基友开黑和和女神约会的时间。这两个时间总是一段连续的时间,小明总是会找最早的时间来开始这些事。当有基友找他开黑的时候,他会先在时间表里找最早的连续时间,如果有,就开黑,没有就不开黑。当有女神和他约会,他先在时间表里找最早的连续时间,如果有就约会,没有他会先不考虑和基友开黑,先和女神约会,如果有时间就约会。

思路:

因为涉及到基友和女神,那线段树里就需要维护两种连续区间,分别为女神的和屌丝的,区间维护三个,左边最大连续区间,右边最大连续区间,和总的最大连续区间。下推标记有三个:学习,屌丝,女神。最容易错的地方是下推标记。当标记学习的时候,屌丝和女神标记应当还原,当标记女神的时候,屌丝标记也应当标记上(因为更新女神所占用的时间的时候,其实屌丝的时间也需要更新)

  1 #include <math.h>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <iostream>
  5 #include <algorithm>
  6 #include <string>
  7 #include <string.h>
  8 #include <vector>
  9 #include <map>
 10 #include <stack>
 11 #include <set>
 12 #include <random>
 13 
 14 #define ll long long
 15 #define ls nod<<1
 16 #define rs (nod<<1)+1
 17 const int maxn = 1e5 + 10;
 18 int n,m;
 19 
 20 struct segment_tree {
 21     int l,r;
 22     int n,d,s;
 23     int nsum,nls,nrs;
 24     int dsum,dls,drs;
 25 }tree[maxn<<2];
 26 
 27 void pushup(int nod) {
 28     tree[nod].dsum = std::max(std::max(tree[ls].dsum,tree[rs].dsum),tree[ls].drs+tree[rs].dls);
 29     tree[nod].dls = tree[ls].dls;
 30     tree[nod].drs = tree[rs].drs;
 31     if (tree[ls].dls == (tree[ls].r - tree[ls].l + 1))
 32         tree[nod].dls = tree[ls].dsum + tree[rs].dls;
 33     if (tree[rs].drs == (tree[rs].r - tree[rs].l + 1))
 34         tree[nod].drs = tree[rs].dsum + tree[ls].drs;
 35 
 36     tree[nod].nsum = std::max(std::max(tree[ls].nsum,tree[rs].nsum),tree[ls].nrs+tree[rs].nls);
 37     tree[nod].nls = tree[ls].nls;
 38     tree[nod].nrs = tree[rs].nrs;
 39     if (tree[ls].nls == (tree[ls].r - tree[ls].l + 1))
 40         tree[nod].nls = tree[ls].nsum + tree[rs].nls;
 41     if (tree[rs].nrs == (tree[rs].r - tree[rs].l + 1))
 42         tree[nod].nrs = tree[rs].nsum + tree[ls].nrs;
 43 }
 44 
 45 void pushdown(int nod) {
 46     if (tree[nod].s == 1) {
 47         tree[ls].dls = tree[ls].drs = tree[ls].dsum = (tree[ls].r - tree[ls].l + 1);
 48         tree[rs].dls = tree[rs].drs = tree[rs].dsum = (tree[rs].r - tree[rs].l + 1);
 49         tree[ls].nls = tree[ls].nrs = tree[ls].nsum = (tree[ls].r - tree[ls].l + 1);
 50         tree[rs].nls = tree[rs].nrs = tree[rs].nsum = (tree[rs].r - tree[rs].l + 1);
 51         tree[ls].s = tree[rs].s = tree[nod].s;
 52         tree[ls].n = tree[rs].n = -1;
 53         tree[ls].d = tree[rs].d = -1;
 54         tree[nod].s = -1;
 55     }
 56     if (tree[nod].n == 1) {
 57         tree[ls].nls = tree[ls].nrs = tree[ls].nsum = tree[rs].nls = tree[rs].nrs = tree[rs].nsum = 0;
 58         tree[ls].n = tree[rs].n = tree[nod].n;
 59         tree[nod].n = -1;
 60     }
 61     if (tree[nod].d == 1) {
 62         tree[ls].dls = tree[ls].drs = tree[ls].dsum = tree[rs].dls = tree[rs].drs = tree[rs].dsum = 0;
 63         tree[ls].d = tree[rs].d = tree[nod].d;
 64         tree[nod].d = -1;
 65     }
 66 }
 67 
 68 void build(int l,int r,int nod) {
 69     tree[nod].l = l;
 70     tree[nod].r = r;
 71     tree[nod].n = tree[nod].s = tree[nod].d = -1;
 72     tree[nod].dls = tree[nod].drs = tree[nod].dsum = (r - l + 1);
 73     tree[nod].nls = tree[nod].nrs = tree[nod].nsum = (r - l + 1);
 74     if (l == r)
 75         return ;
 76     int mid = (l + r ) >> 1;
 77     build(l,mid,ls);
 78     build(mid+1,r,rs);
 79 }
 80 
 81 void modify(int x,int y,int flag,int nod=1) {
 82     int l = tree[nod].l,r = tree[nod].r;
 83     if (x <= l && y >= r) {
 84         if (flag == 1) {
 85             tree[nod].nls = tree[nod].nrs = tree[nod].nsum = tree[nod].dls = tree[nod].drs = tree[nod].dsum = 0;
 86             tree[nod].n = 1;
 87             tree[nod].d = 1;
 88         }
 89         else {
 90             tree[nod].dls = tree[nod].drs = tree[nod].dsum = 0;
 91             tree[nod].d = 1;
 92         }
 93         return ;
 94     }
 95     pushdown(nod);
 96     int mid = (l + r) >> 1;
 97     if (x <= mid) {
 98         modify(x,y,flag,ls);
 99     }
100     if (y > mid) {
101         modify(x,y,flag,rs);
102     }
103     pushup(nod);
104 }
105 
106 int queryD(int x,int nod=1) {
107     int l = tree[nod].l,r = tree[nod].r;
108     if (l == r)
109         return l;
110     pushdown(nod);
111     if (x <= tree[ls].dsum) {
112         return queryD(x,ls);
113     }
114     else if (tree[ls].drs + tree[rs].dls >= x) {
115         return tree[ls].r - tree[ls].drs + 1;
116     }
117     else
118         return queryD(x,rs);
119 }
120 
121 int queryN(int x,int nod=1) {
122     int l = tree[nod].l,r = tree[nod].r;
123     if (l == r)
124         return l;
125     pushdown(nod);
126     if (x <= tree[ls].nsum) {
127         return queryN(x,ls);
128     }
129     else if (tree[ls].nrs + tree[rs].nls >= x) {
130         return tree[ls].r - tree[ls].nrs + 1;
131     }
132     else
133         return queryN(x,rs);
134 }
135 
136 void clean(int x,int y,int nod=1) {
137     int l = tree[nod].l,r = tree[nod].r;
138     if (x <= l && y >= r) {
139         tree[nod].dls = tree[nod].drs = tree[nod].dsum = tree[nod].nls = tree[nod].nrs = tree[nod].nsum = (r - l + 1);
140         tree[nod].s = 1;
141         tree[nod].n = -1;
142         tree[nod].d = -1;
143         return ;
144     }
145     pushdown(nod);
146     int mid = (l + r) >> 1;
147     if (x <= mid) {
148         clean(x,y,ls);
149     }
150     if (y > mid) {
151         clean(x,y,rs);
152     }
153     pushup(nod);
154 }
155 
156 int main() {
157     int Case;
158     int t = 1;
159     scanf("%d",&Case);
160     while (Case--) {
161         scanf("%d%d",&n,&m);
162         build(1,n,1);
163         printf("Case %d:
",t++);
164         while (m--) {
165             int num,x,y;
166             char str[10];
167             scanf("%s",str);
168             if (str[0] == 'D') {
169                 scanf("%d",&num);
170                 if (tree[1].dsum < num) {
171                     printf("fly with yourself
");
172                 }
173                 else {
174                     int ans = queryD(num);
175                     printf("%d,let's fly
",ans);
176                     modify(ans,ans+num-1,2);
177                 }
178             }
179             else if (str[0] == 'N') {
180                 scanf("%d",&num);
181                 if (tree[1].nsum < num) {
182                     printf("wait for me
");
183                 }
184                 else {
185                     if (tree[1].dsum >= num) {
186                         int ans = queryD(num);
187                         printf("%d,don't put my gezi
",ans);
188                         modify(ans,ans+num-1,1);
189                     }
190                     else if (tree[1].nsum >= num) {
191                         int ans = queryN(num);
192                         printf("%d,don't put my gezi
",ans);
193                         modify(ans,ans+num-1,1);
194                     }
195                 }
196             }
197             else {
198                 scanf("%d%d",&x,&y);
199                 clean(x,y,1);
200                 printf("I am the hope of chinese chengxuyuan!!
");
201             }
202         }
203     }
204     return 0;
205 }
原文地址:https://www.cnblogs.com/-Ackerman/p/11729306.html