64分 4个点WA线段树求助
  • 板块P1503 鬼子进村
  • 楼主Xeqwq
  • 当前回复4
  • 已保存回复4
  • 发布时间2022/8/30 18:06
  • 上次更新2023/10/27 13:03:04
查看原帖
64分 4个点WA线段树求助
229373
Xeqwq楼主2022/8/30 18:06

线段树+二分,二分两边最多可以走多少个屋子。

#include <iostream>
#include <stack>
using namespace std;
inline int lc(int p){return p<<1;}
inline int rc(int p){return p<<1|1;}
const int Maxn=5e4+5;
char op[2];
int n,m;
int sum[Maxn<<2];
int a[Maxn];
void pushup(int p)
{
	sum[p]=sum[lc(p)]+sum[rc(p)];
}
void build(int p,int l,int r)
{
	if(l==r)
	{
		sum[p]=a[l]=1;
		return;
	}
	int mid=(l+r)>>1;
	build(lc(p),l,mid);
	build(rc(p),mid+1,r);
	pushup(p);
}
void modify(int p,int l,int r,int x,int k)
{
	if(l==r)
	{
		sum[p]=k;
		return;
	}
	int mid=(l+r)>>1;
	if(x<=mid) modify(lc(p),l,mid,x,k);
	else modify(rc(p),mid+1,r,x,k);
	pushup(p);
}
int query(int p,int l,int r,int ql,int qr)
{
	if(ql<=l&&r<=qr) return sum[p];
	int ret=0,mid=(l+r)>>1;
	if(ql<=mid) ret+=query(lc(p),l,mid,ql,qr);
	if(mid<qr) ret+=query(rc(p),mid+1,r,ql,qr);
	return ret;
}
stack<int> s;
int main()
{
	cin>>n>>m;
	build(1,1,n);
	int last=0,x,ans,mid,ret;
	while(m--)
	{
		scanf("%s",op);
		if(op[0]=='D')
		{
			scanf("%d",&x);
			s.push(x);
			a[x]=0;
			modify(1,1,n,x,0);
		}
		else if(op[0]=='R')
		{
			last=s.top();
			s.pop();
			a[last]=1;
			modify(1,1,n,last,1);
		}
		else
		{
			scanf("%d",&x);
			if(!a[x])
			{
				printf("0\n");
				continue;
			}
			ans=1;
			if(x!=1)
			{
				int l=1,r=x-1;
				ret=x;
				while(l<=r)
				{
					mid=(l+r)>>1;
					if(query(1,1,n,mid,x-1)==x-mid)
					{
						ret=mid;
						r=mid-1;
					}
					else l=mid+1;
				}
				ans+=(x-ret);
			}
//			cout<<x-ret<<" ";
			if(x!=n)
			{
				int l=x+1,r=n;
				while(l<=r)
				{
					mid=(l+r)>>1;
					if(query(1,1,n,x+1,mid)==mid-x)
					{
						ret=mid;
						l=mid+1;
					}
					else r=mid-1;
				}
				ans+=(ret-x);
			}
//			cout<<x-ret+2<<" ";
			printf("%d\n",ans); 
		}
	}
}
2022/8/30 18:06
加载中...