您的位置:首页 > 其它

POJ -2892 Tunnel Warfare - 线段树区间合并

2016-11-24 15:12 441 查看
LINK:http://poj.org/problem?id=2892

//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<stack>

using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=50010;
int num[maxn<<2],ls[maxn<<2],rs[maxn<<2];
bool mark[maxn]={0};
void pushup(int rt,int m)
{
ls[rt]=ls[rt<<1];
rs[rt]=rs[rt<<1|1];
if(ls[rt]>=m-(m>>1))ls[rt]+=ls[rt<<1|1];
if(rs[rt]>=(m>>1))rs[rt]+=rs[rt<<1];
}
void build(int l,int r,int rt)
{
ls[rt]=rs[rt]=num[rt]=r-l+1;
if(l==r)return;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void update(int p,int c,int l,int r,int rt)
{
if(l==r)
{
ls[rt]=(rs[rt]+=c);
return;
}
int m=(l+r)>>1;
if(p<=m)
{
update(p,c,lson);
}
else
update(p,c,rson);
pushup(rt,r-l+1);
}
int queryL(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)return ls[rt];
int m=(l+r)>>1,ans1,ans2;
if(L<=m)ans1=queryL(L,R,lson);
if(R>m)ans2=queryL(L,R,rson);
if(R<=m)return ans1;
if(L>m)return ans2;
if(ans1==m-L+1)return ans1+ans2;
return ans1;
}
int queryR(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)return rs[rt];
int m=(l+r)>>1,ans1,ans2;
if(L<=m)ans1=queryR(L,R,lson);
if(R>m)ans2=queryR(L,R,rson);
if(R<=m)return ans1;
if(L>m)return ans2;
if(ans2==R-m)return ans1+ans2;
return ans2;
}
int main()
{
stack<int>q;
char a[5];
int n,m,k;
while(~scanf("%d%d",&n,&m))
{
while(!q.empty())q.pop();
getchar();
build(1,n,1);
for(int i=0;i<m;i++)
{
scanf("%s",a);
if(a[0]=='D')
{
scanf("%d",&k);
q.push(k);mark[k]=1;
update(k,-1,1,n,1);
}
else if(a[0]=='R')
{
k=q.top();
while(!mark[k])
{
q.pop();
if(q.empty())goto here;
k=q.top();
}
q.pop();
update(k,1,1,n,1);
mark[k]=0;
}
else
{
scanf("%d",&k);
int ans=queryL(k,n,1,n,1)+queryR(1,k,1,n,1);
printf("%d\n",ans==0?0:ans-1);
}
here :;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj 线段树