POJ 2892 HDU 1540 Tunnel Warfare

来源:互联网 发布:linux防暴力破解 编辑:程序博客网 时间:2024/06/05 16:37

题意:n个村子连成一排。之间可以互相通信。但是可能有些村子被破坏,就会阻隔通信联系。然后这些被破坏的村子能够被修复,且修复的是最近被破坏的村子。给几次询问,问与x通信联系的村子有几个,包括x自己。

思路:我是直接用栈模拟,线段树也可以做。

poj能过。hdu过不了:

#include<cstdio>#include<stack>#include<cstring>using namespace std;const int maxn = 5*1e5+100;int de[maxn];int main(){int n,m;//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);while(~scanf("%d%d",&n,&m)){memset(de,0,sizeof(de));stack<int> s;while(m--){char op[5];int x;scanf("%s%d",op);if(op[0]=='R'){if(!s.empty()){de[s.top()]=0;s.pop();}}else if(op[0]=='D'){de[x]=1;s.push(x);}else if(op[0]=='Q'){if(de[x])printf("0\n");else{int rp=0;for(int i=x;i<=n&&!de[i];i++)rp++;for(int i=x-1;i>=1&&!de[i];i--)rp++;printf("%d\n",rp);}}}}} 

线段树
#include<cstdio>#include<stack>#include<algorithm>using namespace std;const int maxn = 51000;struct SegTree{int l,r;int ll,rr,mm;//分别记录从区间左右开始的最大连续段,及整个区间的最大连续段 }node[maxn*3];void build(int root,int l,int r){node[root].l=l;node[root].r=r;node[root].ll=r-l+1;node[root].rr=r-l+1;node[root].mm=r-l+1;if(l==r)return;int mid=(l+r)>>1;build(2*root,l,mid);build(2*root+1,mid+1,r);}void update(int i,int x,int t){if(node[i].l==node[i].r){if(t==0)node[i].ll=node[i].rr=node[i].mm=0;elsenode[i].ll=node[i].rr=node[i].mm=1;return;}int mid=(node[i].l+node[i].r)>>1;if(x>mid)update(2*i+1,x,t);else if(x<=mid)update(2*i,x,t);node[i].ll=node[i*2].ll;node[i].rr=node[i*2+1].rr;node[i].mm=max(node[i*2].mm,node[i*2+1].mm);//不考虑中间拼接 node[i].mm=max(node[i].mm,node[i*2].rr+node[i*2+1].ll);//中间拼接 if(node[i*2].ll==node[i*2].r-node[i*2].l+1)node[i].ll+=node[i*2+1].ll;//跨过了左区间 if(node[i*2+1].rr==node[i*2+1].r-node[i*2+1].l+1)node[i].rr+=node[i*2].rr;}int query(int i,int x){if(node[i].l==node[i].r||node[i].mm==0||node[i].mm==node[i].r-node[i].l+1)return node[i].mm;int mid=(node[i].l+node[i].r)>>1;if(x<=mid){if(x>=node[i*2].r-node[i*2].rr+1)//左子区间 的被炸毁点右侧,仍要合并右子区间信息 return query(i*2,x)+query(i*2+1,mid+1);elsereturn query(i*2,x);}else{if(x<=node[i*2+1].l+node[i*2+1].ll-1)return query(i*2,mid)+query(i*2+1,x);elsereturn query(i*2+1,x);}}int main(){int n,m;//freopen("in.txt","r",stdin);while(~scanf("%d%d",&n,&m)){char op[100];stack<int> s;build(1,1,n);while(m--){scanf("%s",op);int x;if(op[0]=='D'){scanf("%d",&x);s.push(x);update(1,x,0);}else if(op[0]=='R'){int x=s.top();s.pop();update(1,x,1);}else{scanf("%d",&x);printf("%d\n",query(1,x));}}}}




原创粉丝点击