题目链接: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 }