Happy Triangle
题目大意
有三种操作:
插入一个值x
删除一个值x
给一个x 问是否在数组里是否有两个值,可以与x构成三角形。
题解
与x构成三角形可以分为几种情况
x是最大边的时候
数组里比x小的最大的两个的和比x大就可以
x不是最大边的时候
找一个值,存在另一个值与这个值的差小于x
这种情况,这个两个值肯定是相邻的因为这样可以保证差最小,
第一种情况可以用set维护,第二种情况,线段树维护最小值就可以。线段树里维护的是与前一个的差值。
代码:
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <cmath>
#include <set>
#include <cstring>
#include <string>
#include <bitset>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef set<int>::iterator sit;
#define st first
#define sd second
#define mkp make_pair
#define pb push_back
void wenjian(){
freopen("concatenation.in","r",stdin);freopen("concatenation.out","w",stdout);}
void tempwj(){
freopen("hash.in","r",stdin);freopen("hash.out","w",stdout);}
ll gcd(ll a,ll b){
return b == 0 ? a : gcd(b,a % b);}
ll qpow(ll a,ll b,ll mod){
a %= mod;ll ans = 1;while(b){
if(b & 1)ans = ans * a % mod;a = a * a % mod;b >>= 1;}return ans;}
struct cmp{
bool operator()(const pii & a, const pii & b){
return a.second > b.second;}};
int lb(int x){
return x & -x;}
const int INF = 0x3f3f3f3f;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const int maxn = 2e5 + 4;
const int M = 4e4+2;
pii pp[maxn];
vector<int> v;
map<int,int> mm;
map<int,int> pos;
set<int> ss;
struct Node
{
int l,r;
ll num;
}node[maxn << 2];
void build(int l,int r,int no)
{
node[no].l = l;
node[no].r = r;
node[no].num = inf;
if(l == r)
{
return;
}
int mid = l + r>> 1;
build(l,mid,no<<1);
build(mid + 1,r,no<<1|1);
}
void update(int pos,ll num,int no)
{
if(node[no].l > pos || node[no].r < pos)
return;
if(node[no].l == node[no].r)
{
node[no].num = num;
return;
}
update(pos,num,no<<1);
update(pos,num,no<<1|1);
node[no].num = min(node[no<<1].num,node[no<<1|1].num);
}
ll query(int l,int r,int no)
{
if(node[no].l > r || node[no].r < l)
return inf;
if(node[no].l >= l &&node[no].r <= r)
{
return node[no].num;
}
return min(query(l,r,no<<1),query(l,r,no<<1|1));
}
int main()
{
int n;
scanf("%d",&n);
for (int i=1 ; i <= n ; i++ )
{
scanf("%d%d",&pp[i].st,&pp[i].sd);
v.pb(pp[i].sd);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
int m = v.size();
build(1,m,1);
for (int i = 0; i < v.size(); i ++ )
{
pos[v[i]] = i + 1;
}
for (int i =1 ; i <= n; i ++ )
{
int f = pp[i].st;
int x = pp[i].sd;
if(f == 1)
{
if(mm[x] == 0)
{
ss.insert(x);
sit it = ss.find(x);
if(it != ss.begin())
{
sit itl = it;
itl -- ;
int s = x - *itl;
update(pos[x],s,1);
// printf("%d %d 111111\n",pos[x],s);
}
sit itr = it;
itr ++;
if(itr != ss.end())
{
int temp = *itr;
if(mm[temp] == 1)
{
update(pos[temp],temp - x,1);
// printf("%d %d 1111111111\n",pos[temp],temp - x);
}
}
}
else
{
update(pos[x],0,1);
// printf("%d %d 1111\n",pos[x],0);
}
mm[x] ++;
}
else if(f == 2)
{
if(mm[x] == 1)
{
sit it = ss.find(x);
sit itr = it;
itr ++;
if(itr != ss.end() && mm[*itr] == 1)
{
int temp = *itr;
if(it == ss.begin())
{
update(pos[temp],inf,1);
// printf("%d %d 11111111\n",pos[temp],-1);
}
else
{
sit itl = it;
itl --;
int t = *itl;
update(pos[temp],temp - t,1);
}
}
update(pos[x],inf,1);
ss.erase(x);
}
else if(mm[x] == 2)
{
sit it = ss.find(x);
if(it != ss.begin())
{
sit itl = it;
itl --;
int temp = *itl;
update(pos[x],x - temp,1);
}
else
{
update(pos[x],inf,1);
}
}
mm[x] -- ;
}
else
{
sit it = ss.lower_bound(x);
if(mm[x] >= 2)
{
printf("Yes\n");
continue;
}
else if(mm[x] == 1 && it != ss.begin())
{
printf("Yes\n");
continue;
}
if(it != ss.begin())
{
sit itl = it;
itl -- ;
int temp = *itl;
if(mm[temp] >= 2 && temp * 2 > x)
{
printf("Yes\n");
continue;
}
if(itl != ss.begin())
{
sit itll = itl;
itll --;
if(*itl + *itll > x)
{
printf("Yes\n");
continue;
}
}
}
ll tt = query(pos[x],m,1);
if(tt < x)
{
printf("Yes\n");
}
else
printf("No\n");
}
}
}