hdu1540 Tunnel Warfare 线段树区间合并

来源:互联网 发布:linux cp 过滤文件夹 编辑:程序博客网 时间:2024/06/08 06:16

题意:n个城镇在一条直线上,初始状态相邻的城镇都相邻。有三种操作:(1) D x 摧毁x城镇 (2) R 修复上次摧毁的城镇 (3) Q x 查询

与x相连的没有被摧毁的城镇。

思路:线段树维护2个变量:ls存区间左端向右连续完好城镇的个数,rs存区间右端向左连续玩好城镇的个数。对于D相当于单点更

新。对于R需要用个栈存之前摧毁的城镇。对于Q稍微麻烦点。要判断p是否在区间的ls、rs里。如果在,那么需要将另一端的与它相

连的部分加上再return。详见代码:

// file name: hdu1540.cpp //// author: kereo //// create time:  2014年09月08日 星期一 16时05分47秒 ////***********************************//#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<set>#include<map>#include<vector>#include<stack>#include<cmath>#include<string>#include<algorithm>using namespace std;typedef long long ll;const int MAXN=50000+100;const int inf=0x3fffffff;const int mod=1000000000+7;#define L(x) (x<<1)#define R(x) (x<<1|1)int n,m,top;int s[MAXN];struct node{int l,r;int ls,rs; //ls记录从区间左端向右连续没有被破坏的village个数,rs记录从右段向左。}segtree[MAXN<<2];void push_up(int rt){segtree[rt].ls=segtree[L(rt)].ls;segtree[rt].rs=segtree[R(rt)].rs;if(segtree[L(rt)].ls == segtree[L(rt)].r-segtree[L(rt)].l+1)segtree[rt].ls+=segtree[R(rt)].ls;if(segtree[R(rt)].rs == segtree[R(rt)].r-segtree[R(rt)].l+1)segtree[rt].rs+=segtree[L(rt)].rs;}void build(int rt,int l,int r){segtree[rt].l=l; segtree[rt].r=r;segtree[rt].ls=segtree[rt].rs=r-l+1;if(l == r)return ;int mid=(l+r)>>1;build(L(rt),l,mid); build(R(rt),mid+1,r);}void update(int rt,int p,int cmd){ //cmd=0,删除;cmd=1,恢复if(segtree[rt].l == segtree[rt].r){segtree[rt].ls=segtree[rt].rs=cmd;return ;}int mid=(segtree[rt].l+segtree[rt].r)>>1;if(p<=mid)update(L(rt),p,cmd);else update(R(rt),p,cmd);push_up(rt);}int query(int rt,int p){//printf("%d %d\n",segtree[rt].l,segtree[rt].r);if(segtree[rt].ls>=p-segtree[rt].l+1)return segtree[rt].ls;if(segtree[rt].rs>=segtree[rt].r-p+1)return segtree[rt].rs;if(segtree[rt].l == segtree[rt].r)return 0;int mid=(segtree[rt].l+segtree[rt].r)>>1;if(p<=mid){int ans=query(L(rt),p);if(segtree[L(rt)].rs>=segtree[L(rt)].r-p+1)ans+=segtree[R(rt)].ls;return ans;}else{int ans=query(R(rt),p);if(segtree[R(rt)].ls>=p-segtree[R(rt)].l+1)ans+=segtree[L(rt)].rs;return ans;}}int main(){while(~scanf("%d%d",&n,&m)){build(1,1,n);top=0;int x;char cmd[2];while(m--){scanf("%s",cmd);if(cmd[0] == 'D'){scanf("%d",&x);s[top++]=x;update(1,x,0);}if(cmd[0] == 'R'){x=s[--top];update(1,x,1);}if(cmd[0] == 'Q'){scanf("%d",&x);;printf("%d\n",query(1,x));}}}return 0;}


0 0