思路:枚举三种情况, 假设三条边分别是 t1, t2, t3 且 t1 <= t2 <= t3。
Case1:t3 = x, 那么只要找两个小于等于 x 的且最接近 x 的数就好了,通过 map 维护集合可方便的求出。
Case1:t2 = x, 那么只要找一个最接近 x 且 <= x 和一个最接近 x 且 >= x 的值, 同样可以通过 map 维护集合可方便的求出。
Case1:t1 = x, 注意!!!这里不能找两个 >= x 且最接近 x 的值, 比如 2 3 5 6,我们应该找 5, 6 而不是 2,3, 所以要维护每个值 x 和第一个大于等于 x 的差值,可以用线段树动态开点来维护。
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <string>
#include <string.h>
#include <map>
#include <iostream>
#include <set>
#include <unordered_map>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
const int maxn = 1e7 + 50;
const LL mod = 998244353;
LL INF = 1e13 + 7;
#define fi first
#define se second
map<LL, int> mmap;
int tot;
struct node
{
int lc, rc;
LL dat;
} tree[maxn];
int Build(){
tot++;
tree[tot].lc = tree[tot].rc;
tree[tot].dat = INF;
return tot;
}
void PushUp(int rt){
LL res = INF;
if(tree[rt].lc){
res = min(tree[tree[rt].lc].dat, res);
}
if(tree[rt].rc){
res = min(tree[tree[rt].rc].dat, res);
}
tree[rt].dat = res;
}
void Update(int le, int ri, int pos, LL mi, int rt){
if(le == ri){
tree[rt].dat = mi;
return ;
}
int m = (le + ri) >> 1;
if(pos <= m){
if(tree[rt].lc == 0) tree[rt].lc = Build();
Update(le, m, pos, mi, tree[rt].lc);
} else {
if(tree[rt].rc == 0) tree[rt].rc = Build();
Update(m + 1, ri, pos, mi, tree[rt].rc);
}
PushUp(rt);
}
LL Query(int le, int ri, int L, int R, int rt){
if(L <= le && ri <= R) return tree[rt].dat;
int m = (le + ri) >> 1;
LL res = INF;
if(L <= m && tree[rt].lc) {
res = min(res, Query(le, m, L, R, tree[rt].lc));
}
if(R > m && tree[rt].rc){
res = min(res, Query(m + 1, ri, L, R, tree[rt].rc));
}
return res;
}
int main(int argc, char const *argv[])
{
int q;
scanf("%d", &q);
mmap[INF] = mmap[-INF] = 2;
Update(1, 1e9 + 7, INF, INF, 0);
while(q--){
int op;
LL x;
scanf("%d%lld", &op, &x);
if(op == 1){
mmap[x]++;
auto it = mmap.lower_bound(x);
if(mmap[x] == 1){
it++;
Update(1, 1e9 + 7, x, it -> fi - x, 0);
it--, it--;
if(it -> se == 1){
Update(1, 1e9 + 7, it -> fi, x - it -> fi, 0);
}
} else {
Update(1, 1e9 + 7, x, 0, 0);
}
} else if(op == 2){
auto it = mmap.lower_bound(x);
if(mmap[x] == 1){
it--;
if(it -> se == 1){
LL le = it -> fi;
it++, it++;
Update(1, 1e9 + 7, le, it -> fi - le, 0);
}
Update(1, 1e9 + 7, x, INF, 0);
mmap.erase(x);
} else if(mmap[x] == 2){
it++;
Update(1, 1e9 + 7, x, it -> fi - x, 0);
mmap[x]--;
} else {
mmap[x]--;
}
} else {
int flag = 0;
auto it = mmap.lower_bound(x);
LL res = Query(1, 1e9 + 7, it -> fi, 1e9 + 7, 0);
if(x > res) flag = 1;
LL t1, t2, t3;
t2 = x;
if(mmap.count(x)){
t3 = x;
it--;
t1 = it -> fi;
it++;
} else {
t3 = it -> fi;
it--;
t1 = it -> fi;
it++;
}
if(t1 + t2 > t3 && t1 != -INF && t3 != INF) flag = 1;
it--;
t3 = x;
if(it -> se > 1){
t1 = t2 = it -> fi;
} else {
t2 = it -> fi;
it--;
t1 = it -> fi;
}
if(t1 + t2 > t3 && t1 != -INF && t2 != -INF) flag = 1;
if(flag){
printf("Yes\n");
} else {
printf("No\n");
}
}
}
return 0;
}
来源:oschina
链接:https://my.oschina.net/u/4342102/blog/4375505