原题链接: ​​http://acm.hdu.edu.cn/showproblem.php?pid=1540​


题意:

一条直线,n个点,标号1-----n,m个操作,规则如下:

D x :摧毁点x

Q x  :查询包含点x的最长序列

R : 恢复上一次被摧毁的一个点

思路就是:我们把所有点初始为1,摧毁该点就赋值为0,用栈保存摧毁的点,当需要恢复时就取出栈顶,进行更新。


#define _CRT_SECURE_NO_DEPRECATE 

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;

int s[50005];//模拟栈,把删除的数放进去,待rebuild的时候取出
int top;

struct Node
{
int l, r, mid;
int len;
int lsum, rsum, msum;
}p[50005 * 4];

void pushUp(int n)
{
p[n].lsum = p[n * 2].lsum + (p[n * 2].lsum == p[n * 2].len ? p[n * 2 + 1].lsum : 0);
p[n].rsum = p[n * 2 + 1].rsum + (p[n * 2 + 1].rsum == p[n * 2 + 1].len ? p[n * 2].rsum : 0);
p[n].msum = max(max(p[n * 2].msum, p[n * 2 + 1].msum), p[n * 2].rsum + p[n * 2 + 1].lsum);
}

void build(int n, int l, int r)
{
p[n].l = l;
p[n].r = r;
p[n].mid = (l + r) / 2;
p[n].len = r - l + 1;
p[n].lsum = p[n].rsum = p[n].msum = p[n].len;
if (l == r)
return;

build(n * 2, l, p[n].mid);
build(n * 2 + 1, p[n].mid + 1, r);
}

void update(int n, int pos, int c)
{
if (p[n].l == p[n].r)
{
if (c == 1)
p[n].lsum = p[n].rsum = p[n].msum = 1;//rebuild
else
p[n].lsum = p[n].rsum = p[n].msum = 0;//destroy

return;//要return,害死人啊
}

if (pos <= p[n].mid)
update(n * 2, pos, c);
else
update(n * 2 + 1, pos, c);

pushUp(n);
}

int query(int n, int pos)
{
if (p[n].l == p[n].r || p[n].msum == p[n].len || p[n].msum == 0)//到了叶子节点或者该访问区间为空或者已满都不必要往下走了
return p[n].msum;

if (pos <= p[n].mid)
{
if (pos >= p[n * 2].r - p[n * 2].rsum + 1)
return p[n * 2].rsum + p[n * 2 + 1].lsum;
else
return query(n * 2, pos);
}
else
{
if (pos <= p[n * 2 + 1].l + p[n * 2 + 1].lsum - 1)
return p[n * 2].rsum + p[n * 2 + 1].lsum;
else
return query(n * 2 + 1, pos);
}
}

int main()
{
char ch[5];
int n, m;
int pos;
while (~scanf("%d%d", &n, &m))
{
top = 0;

build(1, 1, n);

while (m--)
{
scanf("%s", ch);

if (ch[0] == 'D')
{
scanf("%d", &pos);
s[top++] = pos;
update(1, pos, 0);//0代表destroy
}
else if (ch[0] == 'Q')
{
scanf("%d", &pos);
printf("%d\n", query(1, pos));
}
else
{
if (top > 0)//栈还有数的话,注意这里要判断
{
pos = s[--top];
update(1, pos, 1);//1代表rebuild
}
}
}
}

return 0;
}