您的位置:首页 > 其它

HDU 1540 Tunnel Warfare

2015-09-01 00:08 465 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540

题意:有n个相邻的村子,D操作将该村子与左右的连接切断,R操作是将上次切断的道路恢复,Q操作是询问包括x在内的连续的村子

思路:线段树区间合并,和hotel不一样的是这题是单点更新,更新大同小异,因为是单点更新所以没用lazy标志,询问的时候比较不一样,判断改点是否在横跨左右子数的区间内,是则直接输出答案,否则继续向子树查询

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
#define maxn 50030
using namespace std;

struct Tree
{
int l,r;
int lsum,rsum;
}tree[maxn*3];

stack <int> s;

void Pushup(int root)
{
int ll=tree[root<<1].r-tree[root<<1].l+1;
tree[root].lsum=tree[root<<1].lsum;
if (tree[root].lsum==ll) tree[root].lsum+=tree[root<<1|1].lsum;
//cout<<":"<<root<<endl;
int rr=tree[root<<1|1].r-tree[root<<1|1].l+1;
tree[root].rsum=tree[root<<1|1].rsum;
if (tree[root].rsum==rr) tree[root].rsum+=tree[root<<1].rsum;
}

void build(int root,int l,int r)
{
tree[root].l=l;
tree[root].r=r;
tree[root].lsum=r-l+1;
tree[root].rsum=r-l+1;
if (l==r) return;
int mid=(l+r)>>1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
Pushup(root);
}

void update(int root,int gold,int val)
{
//cout<<":"<<root<<endl;
if (tree[root].l==tree[root].r)
{
if (val==0) tree[root].lsum=tree[root].rsum=0;
else tree[root].lsum=tree[root].rsum=1;
return;
}

int mid=(tree[root].l+tree[root].r)>>1;
if (gold<=mid) update(root<<1,gold,val);
else if (gold>mid) update(root<<1|1,gold,val);
Pushup(root);
// cout<<":"<<root<<endl;
}

int que(int root,int gold)
{

if (tree[root].l==tree[root].r ) return tree[root].lsum;
int mid=(tree[root].l+tree[root].r)>>1;
int ll=mid-tree[root<<1].rsum+1;
int rr=mid+tree[root<<1|1].lsum;//cout<<ll<<":"<<rr<<endl;
if (gold>=ll && gold <=rr) return tree[root<<1].rsum+tree[root<<1|1].lsum;
else if (gold<ll) return que(root<<1,gold);
else if (gold>rr) return que(root<<1|1,gold);

}

int main()
{
int n,m;
while (scanf("%d%d",&n,&m)!=EOF)
{
//while (s.size()) s.pop();
build(1,1,n);
for (int i=0;i<m;i++)
{
char tem;
cin>>tem;
if (tem=='D')
{
int a;
scanf("%d",&a);
update(1,a,0);
s.push(a);
}
else if (tem=='R')
{
int a=s.top();
s.pop();
update(1,a,1);
}
else if (tem=='Q')
{
int a;
scanf("%d",&a);
printf("%d\n",que(1,a));
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: