H-Happy Triangle 2020牛客暑期多校训练营(第二场)

https://ac.nowcoder.com/acm/contest/5667/H

离散化后用set和数量数组num维护这个multiset

对于询问3,如果x是作为最长边,那么我们只需要找到集合中刚好<=x的两个边,如果作为中间边,就找到大小相邻的两个,如果作为最小边,那么就去>x的所有边中找两个大小相邻的a<=b,使得x+a>b,也就是b-a<x,也就是大小相邻的最小的要小于x就行了

在维护multiset的时候顺便用线段树维护每一个离散后的值i,他如果在集合中,且有<=i的值,他们之间的最小差值是多少,然后就可以求出一个id(x)--tot的最小差值

set的细节有点难搞,应该有好点的写法,因为对于>=x的值有两个相同在集合中的就一定有解,我写复杂了

#include<bits/stdc++.h>
using namespace std;

const int maxl=4e5+10;
const int inf=2e9+10;

int n,q,tot,ans;
int a[maxl],num[maxl],b[6];
struct query
{
	int op,x;
}que[maxl];
set<int> s;
set<int> ::iterator it;
struct node
{
	int l,r,mi;
}tree[maxl*4];

inline void build(int k,int l,int r)
{
	tree[k].l=l;tree[k].r=r;
	if(l==r)
	{
		tree[k].mi=inf;
		return;
	}
	int mid=(l+r)>>1;	
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	tree[k].mi=min(tree[k<<1].mi,tree[k<<1|1].mi);
}

inline void upd(int k,int l,int x)
{
	if(tree[k].l==tree[k].r)
	{
		tree[k].mi=x;
		return;
	}
	int mid=(tree[k].l+tree[k].r)>>1;
	if(l<=mid)
		upd(k<<1,l,x);
	else
		upd(k<<1|1,l,x);
	tree[k].mi=min(tree[k<<1].mi,tree[k<<1|1].mi);		
}

inline int qry(int k,int l,int r)
{
	if(tree[k].l==l && tree[k].r==r)
		return tree[k].mi;
	int mid=(tree[k].l+tree[k].r)>>1;
	if(r<=mid)
		return qry(k<<1,l,r);
	else if(l>mid)
		return qry(k<<1|1,l,r);
	else
		return min(qry(k<<1,l,mid),qry(k<<1|1,mid+1,r));	
}

inline int id(int x)
{
	return lower_bound(a+1,a+1+tot,x)-a;
}

inline void prework()
{
	scanf("%d",&q);tot=0;
	for(int i=1;i<=q;i++)
	{
		scanf("%d",&que[i].op);
		scanf("%d",&que[i].x);
		a[++tot]=que[i].x;
	}
	sort(a+1,a+1+tot);
	tot=unique(a+1,a+1+tot)-a-1;
	build(1,1,tot);
}

inline void mainwork()
{
	int ind,val,rx,lx,rind,lind,l,r;
	for(int i=1;i<=q;i++)
	if(que[i].op==1)
	{
		ind=id(que[i].x);
		num[ind]++;
		if(num[ind]==2)
			upd(1,ind,0);
		else if(num[ind]==1)
		{
			it=s.lower_bound(que[i].x);
			if(it!=s.end())
			{
				rx=(*it);rind=id(rx);
				if(num[rind]==1)
					upd(1,rind,rx-que[i].x)	;
			}
			if(it!=s.begin())
			{
				--it;
				lx=(*it);lind=id(lx);
				upd(1,ind,que[i].x-lx);	
			}
			s.insert(que[i].x);
		}
	}
	else if(que[i].op==2)
	{
		ind=id(que[i].x);
		num[ind]--;
		if(num[ind]==1)
		{
			it=s.lower_bound(que[i].x);
			if(it!=s.begin())
			{
				--it;
				lx=(*it);lind=id(lx);
				upd(1,ind,que[i].x-lx);
			}
			else
				upd(1,ind,inf);
		}else if(num[ind]==0)
		{
			upd(1,ind,inf);
			it=s.lower_bound(que[i].x);
			++it;
			if(it!=s.end())
			{
				rx=(*it);rind=id(rx);
				if(num[rind]==1)
				{
					--it;
					if(it!=s.begin())
					{
						--it;
						lx=(*it);lind=id(lx);
						upd(1,rind,rx-lx);
					}
					else
						upd(1,rind,inf);
				}
			}
			s.erase(s.lower_bound(que[i].x));
		}
	}
	else
	{
		l=3,r=3;b[3]=que[i].x;ind=id(que[i].x);
		it=s.lower_bound(que[i].x);
		if(it!=s.end())
		{
			rx=(*it);rind=id(rx);
			if(num[rind]==1)
			{
				b[++r]=rx;
				++it;
				if(it!=s.end())
					b[++r]=(*it);
				--it;
			}
			else
				b[++r]=rx,b[++r]=rx;
		}
		if(it!=s.begin())
		{
			--it;
			lx=(*it);lind=id(lx);
			if(num[lind]==1)
			{
				b[--l]=lx;
				if(it!=s.begin())
				{
					--it;
					b[--l]=(*it);
				}
			}
			else
				b[--l]=lx,b[--l]=lx;
		}
		ans=0;
		for(int i=l;i<=r-2;i++)
		if(b[i]+b[i+1]>b[i+2])
			ans=1;
		if(!ans && r==5 && id(b[5])<=tot)
			if(qry(1,id(b[5]),tot)<que[i].x)
				ans=1;
		if(ans)
			puts("Yes");
		else
			puts("No");
	}
}

int main()
{
	prework();
	mainwork();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/107322925
今日推荐