2020牛客暑期多校训练营(第二场)H Happy Triangle

爱⌒轻易说出口 提交于 2020-10-04 03:10:49

思路:枚举三种情况, 假设三条边分别是 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;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!