您的位置:首页 > 其它

HDU1540Tunnel Warfare(线段树区间合并)

2017-03-15 18:33 260 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540

题目大意:

一条线上的点,D x是破坏这个点,Q x是表示查询以x所在的最长的连续的点的个数,R是恢复上一次破坏的点。

分析:

线段树结点 设置一个  ll 记录区间左端点开始的最大连续个数,  rl 记录区间右端点开始的最大的连续个数,ml表示该区间最大的连续点的个数。主要是更新和查询两个操作。

收获:
掌握区间合并的方式。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 50005;
struct Node
{
int l, r;
int ll, rl, ml;
}segTree[maxn<<2];
void Build(int rt, int l, int r)
{
segTree[rt].l = l;
segTree[rt].r = r;
segTree[rt].ll = segTree[rt].rl = segTree[rt].ml = r - l + 1;
if(l == r)
return ;
int mid = (l + r) >> 1;
Build(rt<<1, l, mid);
Build((rt<<1)|1, mid+1, r);
}
void update(int rt, int t, int val)
{
if(segTree[rt].l == segTree[rt].r)
{
if(val == 1)
segTree[rt].ll = segTree[rt].rl = segTree[rt].ml = 1;
else
segTree[rt].ll = segTree[rt].rl = segTree[rt].ml = 0;
return ;
}
int mid = (segTree[rt].l + segTree[rt].r) >> 1;
if(t <= mid)
update(rt<<1, t, val);
else
update((rt<<1)|1, t, val);
segTree[rt].ll = segTree[rt<<1].ll;
segTree[rt].rl = segTree[(rt<<1)|1].rl;
segTree[rt].ml = max(segTree[rt<<1].ml, segTree[(rt<<1)|1].ml);
segTree[rt].ml = max(segTree[rt].ml, segTree[rt<<1].rl + segTree[(rt<<1)|1].ll);

if(segTree[rt<<1].ll == segTree[rt<<1].r - segTree[rt<<1].l + 1)
segTree[rt].ll += segTree[(rt<<1)|1].ll;
if(segTree[(rt<<1)|1].rl == segTree[(rt<<1)|1].r - segTree[(rt<<1)|1].l + 1)
segTree[rt].rl += segTree[rt<<1].rl;
}
int query(int rt, int t)
{
if(segTree[rt].l == segTree[rt].r || segTree[rt].ml == 0 || segTree[rt].ml == segTree[rt].r - segTree[rt].l + 1)
{
return segTree[rt].ml;
}
int mid = (segTree[rt].l + segTree[rt].r) >> 1;
if(t <= mid)
{
if(t >= segTree[rt<<1].r - segTree[rt<<1].rl + 1)
return segTree[rt<<1].rl + query((rt<<1)|1, mid+1);
//return query(rt<<1, t) + query((rt<<1)|1, mid+1);
else
return query(rt<<1, t);
}
else
{
if(t <= segTree[(rt<<1)|1].l + segTree[(rt<<1)|1].ll - 1)
return segTree[(rt<<1)|1].ll + query(rt<<1, mid);
//return query((rt<<1)|1, t) + query(rt<<1, mid);
else
return query((rt<<1)|1, t);
}
}
int que[maxn];
int top;
int main()
{
int n, m, x;
char str[10];
while(scanf("%d%d", &n, &m) != EOF)
{
top = 0;
Build(1, 1, n);
while(m--)
{
scanf("%s", str);
if(str[0] == 'D')
{
scanf("%d", &x);
que[top++] = x;
update(1, x, 0);
}
else if(str[0] == 'Q')
{
scanf("%d", &x);
printf("%d\n", query(1, x));
}
else
{
if(x > 0)
{
x = que[--top];
update(1, x, 1);
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: