线段树区间合并, 三种命令, D t
: 请求一段长度为t的连续区间, 返回区间开始位置; N t
: 同上, 但如果没有符合要求, 则忽略之前D的请求再寻找; S t1, t2
: 清空[t1, t2];
维护两个区间合并的线段树, 因为两个线段树功能都是一样的, 所以不需要写双份的代码了, 函数增加一个参数用以表示是哪个线段树;
太久没写了, 写完后WA了, 因为一个rt手抖写成了rt<<1, 一个地方少写了一个update, t是线段树的大小, 但一不小心习惯性地把n当成了线段树大小…一大堆这种错误, 改了好久, 太不熟练了
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
#define ls l, m, rt<<1
#define rs m+1, r, rt<<1|1
#define defm int m = (l+r)>>1
const int MAXN = 1e6 + 1000;
int T, t, n, a, b, c;
struct P { int lsum, rsum, msum, color; };
P ds[MAXN<<2], ns[MAXN<<2];
char op[19];
void pushUp(P p[], int rt, int m)
{
p[rt].lsum = p[rt<<1].lsum;
if(p[rt<<1].lsum == (m-(m>>1))) p[rt].lsum += p[rt<<1|1].lsum;
p[rt].rsum = p[rt<<1|1].rsum;
if(p[rt<<1|1].rsum == (m>>1)) p[rt].rsum += p[rt<<1].rsum;
p[rt].msum = max(p[rt<<1].msum, max(p[rt<<1|1].msum, p[rt<<1].rsum+p[rt<<1|1].lsum) );
}
void pushDown(P p[], int rt, int m)
{
if(p[rt].color!=-1)
{
p[rt<<1].color = p[rt<<1|1].color = p[rt].color;
p[rt<<1].lsum = p[rt<<1].msum = p[rt<<1].rsum = p[rt].color ? 0 : m-(m>>1);
p[rt<<1|1].lsum = p[rt<<1|1].msum = p[rt<<1|1].rsum = p[rt].color ? 0 : (m>>1);
p[rt].color = -1;
}
}
void build(P p[], int l, int r, int rt)
{
p[rt].color = -1;
p[rt].lsum = p[rt].msum = p[rt].rsum = r-l+1;
if(l==r) return;
defm;
build(p, ls);
build(p, rs);
}
int query(P p[], int v, int l, int r, int rt)
{
if(v > p[rt].msum) return 0;
if(l==r) return l;
pushDown(p, rt, r-l+1);
defm;
if(p[rt<<1].msum >= v) return query(p, v, ls);
if(p[rt<<1].rsum + p[rt<<1|1].lsum >= v) return m - p[rt<<1].rsum + 1;
return query(p, v, rs);
}
void update(P p[], int L, int R, int o, int l, int r, int rt)
{
if(L <= l && r <= R)
{
p[rt].color = o;
p[rt].lsum = p[rt].msum = p[rt].rsum = o ? 0 : (r-l+1);
return;
}
if(R < l || r < L) return;
pushDown(p, rt, r-l+1);
defm;
update(p, L, R, o, ls);
update(p, L, R, o, rs);
pushUp(p, rt, r-l+1);
}
int main()
{
scanf("%d", &T);
for(int cas = 1; cas <= T; ++cas)
{
printf("Case %d:\n", cas);
scanf("%d%d", &t, &n);
build(ds, 1, t, 1);
build(ns, 1, t, 1);
for(int i=0; i<n; ++i)
{
scanf("%s%d", op, &a);
if(op[0] == 'D')
{
b = query(ds, a, 1, t, 1);
if(b)
{
printf("%d,let's fly\n", b);
update(ds, b, b+a-1, 1, 1, t, 1);
}
else printf("fly with yourself\n");
}
else if(op[0] == 'N')
{
b = query(ds, a, 1, t, 1);
if(b)
{
printf("%d,don't put my gezi\n", b);
update(ds, b, b+a-1, 1, 1, t, 1);
update(ns, b, b+a-1, 1, 1, t, 1);
}
else
{
c = query(ns, a, 1, t, 1);
if(c)
{
printf("%d,don't put my gezi\n", c);
update(ns, c, c+a-1, 1, 1, t, 1);
update(ds, c, c+a-1, 1, 1, t, 1);
}
else printf("wait for me\n");
}
}
else
{
scanf("%d", &b);
update(ds, a, b, 0, 1, t, 1);
update(ns, a, b, 0, 1, t, 1);
printf("I am the hope of chinese chengxuyuan!!\n");
}
}
}
return 0;
}
Written with StackEdit.