当前位置: 代码迷 >> 综合 >> 2020牛客多校二H Happy Triangle (STL 线段树)
  详细解决方案

2020牛客多校二H Happy Triangle (STL 线段树)

热度:53   发布时间:2024-02-20 00:47:44.0

题意:一个集合可以对其做三种操作,加上一个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;
}