题意:一个集合可以对其做三种操作,加上一个x,减去一个已有x,给出一个x问时候存在a和b使得abx可以围成一个三角形
分析:看到集合操作马上想到用set,其中可以再用set的指针在map上记录下所以数值之间的差,但这时存在一个问题就是可能存在两个数,这两个数的差满足条件但两个数的和却太小不到x,因此我所用的方法就是提前把所有差都求出来后离散键线段树,线段树上存的是该差中的最大和,这样再动态对每个操作进行修改查询
代码:
#include <bits/stdc++.h>
#define x first
#define y second
#define mid (l+r>>1)
#define lo (o<<1)
#define ro (o<<1|1)
using namespace std;
typedef long long ll;
typedef vector<int>vi;
typedef pair<int,ll>pii;
struct tri{int x,y,z;};
const int inf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;
const int N=2e5+10;
const ll mod=1e9+7;
const double PI=acos(0)*2;
int n,m,o[N],x[N];
vector<pii>add[N],sub[N];
set<int>tong[N<<2];
int arr[N<<2];
ll ma[N<<3];
void update(int p,int v,int o=1,int l=1,int r=m)
{
if(l==r)
{
ma[o]=v;
return;
}
if(p<=mid)update(p,v,lo,l,mid);
else update(p,v,ro,mid+1,r);
ma[o]=max(ma[lo],ma[ro]);
}
ll query(int p,int o=1,int l=1,int r=m)
{
if(r<=p)
{
return ma[o];
}
ll ret=query(p,lo,l,mid);
if(p>mid)ret=max(ret,query(p,ro,mid+1,r));
return ret;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
// freopen("in.txt","r",stdin);
map<ll,int>mp,s;
mp[0]=1,mp[inf<<1]=1;
s[inf<<1]=1;
cin>>n;
for(int i=1;i<=n;i++)
{
int op,a;cin>>op>>a;
o[i]=op;x[i]=a;
if(op==1)
{
if(mp.count(a))
{
s[0]++;
add[i].push_back({0,a*2});
}
else
{
auto l=mp.lower_bound(a);
auto r=l--;
int len=r->x-l->x;
s[len]--;
if(s[len]==0)s.erase(len);
sub[i].push_back({len,r->x+l->x});
s[r->x-a]++;
add[i].push_back({r->x-a,r->x+a});
s[a-l->x]++;
add[i].push_back({a-l->x,a+l->x});
}
mp[a]++;
}
else if(op==2)
{
mp[a]--;
if(mp[a]==0)
{
mp.erase(a);
auto l=mp.lower_bound(a);
auto r=l--;
s[r->x-l->x]++;
add[i].push_back({r->x-l->x,r->x+l->x});
int tmp=a-l->x;
s[tmp]--;
if(!s[tmp])s.erase(tmp);
sub[i].push_back({tmp,a+l->x});
tmp=r->x-a;
s[tmp]--;
if(!s[tmp])s.erase(tmp);
sub[i].push_back({tmp,a+r->x});
}
else
{
s[0]--;
if(!s[0])s.erase(0);
sub[i].push_back({0,a*2});
}
}
}
for(int i=1;i<=n;i++)
{
for(auto j:add[i])arr[++m]=j.x;
}
sort(arr+1,arr+1+m);
m=unique(arr+1,arr+1+m)-arr;
// for(int i=1;i<=m;i++)cout<<arr[i]<<' ';cout<<endl;
unordered_map<int,int>id;
for(int i=1;i<=m;i++)id[arr[i]]=i;
for(int i=1;i<=n;i++)
{
for(auto j:add[i])
{
tong[id[j.x]].insert(j.y);
update(id[j.x],*(--tong[id[j.x]].end()));
}
for(auto j:sub[i])if(j.x!=inf*2)
{
tong[id[j.x]].erase(j.y);
int tmp=0;
if(tong[id[j.x]].size())tmp=*(--tong[id[j.x]].end());
update(id[j.x],tmp);
}
if(o[i]==3)
{
int p=lower_bound(arr+1,arr+1+m,x[i])-arr;
// cout<<p<<endl;
if(p>1&&query(p-1)>x[i])
{
// cout<<p-1<<' '<<query(p-1)<<endl;
cout<<"Yes"<<endl;
}
else cout<<"No"<<endl;
}
}
return 0;
}