POJ 2892 Tunnel Warfare 区间合并线段树

做法:hdu的较严格,加上while即可

#include<cstdio>
#include<cstring>
#include<stack>
#define left l,m,x<<1
#define right m+1,r,x<<1|1
const int LMT=50005;
using namespace std;
int lsum[LMT<<2],rsum[LMT<<2],cov[LMT<<2],n;
bool vis[LMT];
stack<int>q;
void cut(int x,int len)
{
	if(cov[x]!=-1)
	{
		cov[x<<1]=cov[x<<1|1]=cov[x];
		lsum[x<<1]=rsum[x<<1]=(len-(len>>1))*cov[x];
		lsum[x<<1|1]=rsum[x<<1|1]=cov[x]*(len>>1);
		cov[x]=-1;
	}
}
void pushup(int x,int len)
{
	lsum[x]=lsum[x<<1];
	rsum[x]=rsum[x<<1|1];
	if(lsum[x]==len-(len>>1))lsum[x]+=lsum[x<<1|1];
	if(rsum[x]==len>>1)rsum[x]+=rsum[x<<1];
	//if(lsum[x]==rsum[x]&&lsum[x]==0)cov[x]=0;
	//if(lsum[x]==rsum[x]&&lsum[x]==len)cov[x]=1;
}
int query(int &tag,int pos,int l,int r,int x)
{
	if(cov[x]!=-1)
	{
		tag=cov[x];
		return (r-l+1)*cov[x];
	}
	cut(x,r-l+1);
	int m=(l+r)>>1,mytag,res=0,len=r-l+1;
	if(pos<=m)
	{
		res+=query(mytag,pos,left);
		switch(mytag)
		{
		case 0:tag=0;break;
		case 1:
			res+=lsum[x<<1|1];
			if(lsum[x<<1|1]==len>>1)tag=1;
			else tag=2;
			break;
		case 2:tag=2;break;
		case 3:res+=lsum[x<<1|1];
			if(lsum[x<<1|1]==len>>1)tag=3;
			else tag=4;
			break;
		case 4:tag=4;break;
		}
	}
	if(pos>m)
	{
		res+=query(mytag,pos,right);
		switch(mytag)
		{
		case 0:tag=0;break;
		case 1:
			res+=rsum[x<<1];
			if(rsum[x<<1]==len-(len>>1))tag=1;
			else tag=3;
			break;
		case 2:res+=rsum[x<<1];
			if(rsum[x<<1]==len-(len>>1))tag=2;
			else tag=4;
			break;
		case 3:tag=3;break;
		case 4:tag=4;break;
		}
	}
	return res;
}
void update(int op,int pos,int l,int r,int x)
{
	if(l==r)
	{
		cov[x]=op;
		lsum[x]=rsum[x]=op;
		return;
	}
	cut(x,r-l+1);
	int m=(l+r)>>1;
	if(pos<=m)update(op,pos,left);
	if(pos>m)update(op,pos,right);
	pushup(x,r-l+1);
}
void init()
{
	int i;
	memset(cov,0,sizeof(cov));
	for(i=0;i<n;i++)
		update(1,i,0,n-1,1);
	memset(vis,1,sizeof(vis));
	while(!q.empty())q.pop();
}
int main(void)
{
	char op;
	int pos,pre,tag,m;
	scanf("%d%d",&n,&m);
		init();
		while(m--)
		{
			op=getchar();
			while(op!='D'&&op!='R'&&op!='Q')op=getchar();
			if(op=='D')
			{
				scanf("%d",&pre);
				pre--;
				vis[pre]=0;
				q.push(pre);
				update(0,pre,0,n-1,1);
			}
			if(op=='R')
			{
				while(!q.empty()&&vis[q.top()])q.pop();
				if(!q.empty())
				{
				  vis[q.top()]=1;
				  update(1,q.top(),0,n-1,1);
				  q.pop();
				}
			}
			if(op=='Q')
			{
				scanf("%d",&pos);pos--;
				printf("%d\n",query(tag,pos,0,n-1,1));
			}
		}
	return 0;
}


你可能感兴趣的:(POJ 2892 Tunnel Warfare 区间合并线段树)