zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第二场)H Happy Triangle

    思路:枚举三种情况, 假设三条边分别是 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
    ");
               } else {
                   printf("No
    ");
               }
           }   
       }
       return 0;
    }
    
  • 相关阅读:
    c语言基础学习10_文件操作02
    c语言_文件操作_FILE结构体小解释
    初识 Swift编程语言(中文版)
    Jquery滑动门实现
    【一步一步走(1)】远程桌面软件VNC的安装与配置
    并查集 路径压缩(具体解释)
    linux中操作java进程
    HDOJ 3944 DP?
    选择排序与冒泡排序
    UVa145 Gondwanaland Telecom
  • 原文地址:https://www.cnblogs.com/PCCCCC/p/13300903.html
Copyright © 2011-2022 走看看