题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4553
需要3个标记,分别是左区间连续长度,右区间连续长度,中间区间的最大连续长度(最大可以通过更新回溯的过程中,pushup中更新)。
题目的难点是如何找合适的连续区间。
因为题目要求的是最左边的符合题目要求的区间,所以找区间的时候要先看左区间的连续长度,其次是中间区间的连续长度(因为中间可能会有多个连续的区间,所以要递归下去找,顺序一样是从左开始找),最后是右区间的连续长度。
代码量可能会很大,所以要细心,耐心一点。
还有需要注意的是输出最好从样例里复制粘贴。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int Maxn = 1e5+10;
const int mod = 10007;
typedef long long ll;
int DS[Maxn<<2], NS[Maxn<<2], DSmid[Maxn<<2], NSmid[Maxn<<2], DSleft[Maxn<<2], DSright[Maxn<<2],
NSleft[Maxn<<2], NSright[Maxn<<2];
int L, R, op, ans, len;
void pushdown(int cur, int l, int r) {
if(NS[cur] == 0) {
NS[cur<<1] = NS[cur<<1|1] = 0;
NS[cur] = -1;
int mid = (r+l)>>1;
NSmid[cur<<1] = NSleft[cur<<1] = NSright[cur<<1] = (mid-l+1);
NSmid[cur<<1|1] = NSleft[cur<<1|1] = NSright[cur<<1|1] = (r-mid);
}
if(DS[cur] == 0) {
DS[cur<<1] = DS[cur<<1|1] = 0;
DS[cur] = -1;
int mid = (r+l)>>1;
DSmid[cur<<1] = DSleft[cur<<1] = DSright[cur<<1] = (mid-l+1);
DSmid[cur<<1|1] = DSleft[cur<<1|1] = DSright[cur<<1|1] = (r-mid);
}
if(NS[cur] == 1) {
NS[cur<<1] = NS[cur<<1|1] = NS[cur];
NS[cur] = -1;
DSmid[cur<<1] = DSmid[cur<<1|1] = NSmid[cur<<1] = NSmid[cur<<1|1] = 0;
DSleft[cur<<1] = DSright[cur<<1] = DSleft[cur<<1|1] = DSright[cur<<1|1] = 0;
NSleft[cur<<1] = NSright[cur<<1] = NSleft[cur<<1|1] = NSright[cur<<1|1] = 0;
}
if(DS[cur] == 1) {
DS[cur<<1] = DS[cur<<1|1] = DS[cur];
DS[cur] = -1;
DSmid[cur<<1] = DSmid[cur<<1|1] = 0;
DSleft[cur<<1] = DSright[cur<<1] = DSleft[cur<<1|1] = DSright[cur<<1|1] = 0;
}
}
void pushup(int cur, int l, int r) {
int mid = (r+l)>>1;
DSleft[cur] = DSleft[cur<<1]; DSright[cur] = DSright[cur<<1|1];
if(DSleft[cur<<1] == mid-l+1) DSleft[cur] += DSleft[cur<<1|1];
if(DSright[cur<<1|1] == r-mid) DSright[cur] += DSright[cur<<1];
NSleft[cur] = NSleft[cur<<1]; NSright[cur] = NSright[cur<<1|1];
if(NSleft[cur<<1] == mid-l+1) NSleft[cur] += NSleft[cur<<1|1];
if(NSright[cur<<1|1] == r-mid) NSright[cur] += NSright[cur<<1];
DSmid[cur] = DSright[cur<<1]+DSleft[cur<<1|1];
DSmid[cur] = max(DSmid[cur<<1], DSmid[cur]);
DSmid[cur] = max(DSmid[cur<<1|1], DSmid[cur]);
NSmid[cur] = NSright[cur<<1]+NSleft[cur<<1|1];
NSmid[cur] = max(NSmid[cur<<1], NSmid[cur]);
NSmid[cur] = max(NSmid[cur<<1|1], NSmid[cur]);
}
void updata(int cur, int l, int r) {
if(L <= l && r <= R) {
if(op == 1) {
DS[cur] = 1;
DSmid[cur] = DSleft[cur] = DSright[cur] = 0;
} else if(op == 2){
NS[cur] = 1;
DSmid[cur] = DSleft[cur] = DSright[cur] = 0;
NSmid[cur] = NSleft[cur] = NSright[cur] = 0;
} else {
DS[cur] = NS[cur] = 0;
DSmid[cur] = NSmid[cur] = (r-l+1);
NSleft[cur] = NSright[cur] = DSleft[cur] = DSright[cur] = (r-l+1);
}
return;
}
int mid = (r+l)>>1;
pushdown(cur, l, r);
if(L <= mid) updata(cur<<1, l, mid);
if(mid+1 <= R) updata(cur<<1|1, mid+1, r);
pushup(cur, l, r);
}
void DSquery(int cur, int l, int r) {
if(ans != -1) return;
if(DSleft[cur] >= len) ans = l;
else if(DSmid[cur] >= len) {
int mid = (l+r)>>1;
pushdown(cur, l , r);
DSquery(cur<<1, l, mid);
if(DSright[cur<<1]+DSleft[cur<<1|1] >= len && ans == -1) ans = DSright[cur<<1] == 0 ? mid+1 : mid-DSright[cur<<1]+1;
DSquery(cur<<1|1, mid+1, r);
} else if(DSright[cur] >= len) ans = r-(DSright[cur])+1;
}
void NSquery(int cur, int l, int r) {
if(ans != -1) return;
if(NSleft[cur] >= len) ans = l;
else if(NSmid[cur] >= len) {
int mid = (l+r)>>1;
pushdown(cur, l , r);
NSquery(cur<<1, l, mid);
if(NSright[cur<<1]+NSleft[cur<<1|1] >= len && ans == -1) ans = NSright[cur<<1] == 0 ? mid+1 : mid-NSright[cur<<1]+1;
NSquery(cur<<1|1, mid+1, r);
} else if(NSright[cur] >= len) ans = r-(NSright[cur])+1;
}
int main(void)
{
int t, T, M;
scanf("%d", &t);
for(int cas = 1; cas <= t; ++cas) {
scanf("%d%d", &T, &M);
memset(DS, -1, sizeof(DS));
memset(NS, -1, sizeof(NS));
memset(DSmid, 0, sizeof(DSmid));
memset(NSmid, 0, sizeof(NSmid));
op = 3; L = 1; R = T;
updata(1, 1, T);
printf("Case %d:\n", cas);
char ch[20];
while (M--) {
scanf("%s", ch); ans = -1;
if(!strcmp(ch, "DS")) {
scanf("%d", &len);
DSquery(1, 1, T);
if(ans == -1) printf("fly with yourself\n");
else {
printf("%d,let's fly\n", ans);
L = ans; R = ans+len-1; op = 1;
updata(1, 1, T);
}
} else if(!strcmp(ch, "NS")) {
scanf("%d", &len);
DSquery(1, 1, T);
if(ans != -1) {
printf("%d,don't put my gezi\n", ans);
L = ans; R = ans+len-1; op = 2;
updata(1, 1, T);
} else {
NSquery(1, 1, T);
if(ans == -1) printf("wait for me\n");
else {
printf("%d,don't put my gezi\n", ans);
L = ans; R = ans+len-1; op = 2;
updata(1, 1, T);
}
}
} else {
scanf("%d%d", &L, &R);
printf("I am the hope of chinese chengxuyuan!!\n");
op = 3; updata(1, 1, T);
}
}
}
return 0;
}