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;
}