zoukankan      html  css  js  c++  java
  • 2020牛客多校第二场 H题Happy Triangle(动态开点线段树)

    2020牛客多校第二场 H题Happy Triangle(动态开点线段树)

    Happy Triangle

    题意:q次询问,3种操作,1:加入一个x,2:删除一个x,3,问能否在加入的边中找两条与x组成3角形。

    题解:设三角形3边a,b,x;

    其1:a+b>x;

    其2:abs(a-b)<x;

    由于其二的特性,我们要尽量找靠的近的a与b既可,例如,a与b间有一个数c,如果a,b满足公式,那c+b>x,

    b-c<x,所以选c不会影响答案,即可以贪心的找靠在一起的边,那么要满足一条我们至少要使b>=x/2+1,这样a+b才能满足第一个条件(第一的b要特判),然后我们就找大于b的最小的间隔距离(用动态开点线段树既可)。

    #include<iostream>
    #include<cstring>
    #include<map>
    using namespace std;
    #define ll long long
    const ll maxn=1e9+7,inv=2e9+7;
    ll q,op,x,k,cnt;
    ll ans[3000007],lc[3000007],rc[3000007];
    map<ll,ll>ma;
    
    void up(ll &k,ll l,ll r,ll pos,ll z){
        if(!k){
            k=++cnt;
        }
        if(l==r){
            ans[k]=z;
            return;
        }
        ll mid=(l+r)/2;
        if(pos<=mid)up(lc[k],l,mid,pos,z);
        else{
            up(rc[k],mid+1,r,pos,z);
        }
        ans[k]=min(ans[lc[k]],ans[rc[k]]);
    }
    void add(ll x){
        ma[x]++;
        auto it=ma.lower_bound(x),it2=it;
        it++;
        it2--;
        if(it->first!=inv){
            if(it->second<=1){
                up(k,1,maxn,it->first,it->first-x);
            }
            else{
                up(k,1,maxn,it->first,0);
            }
        }
        if(ma[x]<=1){
            up(k,1,maxn,x,x-it2->first);
        }
        else{
            up(k,1,maxn,x,0);
        }
    }
    void del(ll x){
        auto it=ma.lower_bound(x),it2=it;
        it++;
        it2--;
        ma[x]--;
        if(ma[x]==0){
            ma.erase(x);
            up(k,1,maxn,x,inv);
            if(it->first!=inv&&it->second==1){
                up(k,1,maxn,it->first,it->first-it2->first);
            }
        }
        else if(ma[x]==1){
            up(k,1,maxn,x,x-it2->first);
        }
    }
    ll findz(ll k,ll l,ll r,ll ql,ll qr){
        if(ql<=l&&r<=qr){
            return ans[k];
        }
        ll mid=(l+r)/2,ans1=inv,ans2=inv;
        if(ql<=mid){
            ans1=findz(lc[k],l,mid,ql,qr);
        }
        if(qr>mid){
            ans2=findz(rc[k],mid+1,r,ql,qr);
        }
        return min(ans1,ans2);
    }
    
    ll query(ll x){
        ll qans=inv;
        auto it=ma.lower_bound(x/2+1),it2=it;
        it2--;
        if(it->first==inv){
            return inv;
        }
        if(it->second>=2){
            qans=0;
        }
        if(it->first+it2->first>x){
            qans=min(it->first-it2->first,qans);
        }
        it++;
        if(it->first==inv){
            return qans;
        }
        else{
            qans=min(qans,findz(k,1,maxn,it->first,maxn));
        }
        return qans;
    }
    int main(){
        memset(ans,inv,sizeof(ans));
        scanf("%lld",&q);
        ma[-inv]++;
        ma[inv]++;
        while(q--){
            scanf("%lld%lld",&op,&x);
            if(op==1){
                add(x);
            }
            if(op==2){
                del(x);
            }
            if(op==3){
                if(query(x)<x){
                    printf("Yes
    ");
                }
                else{
                    printf("No
    ");
                }
            }
        }
    }
    
    
  • 相关阅读:
    Python中的list和tuple
    Python中输出格式化的字符串
    Python笔记-第一天
    在Lingo中输入矩阵(通过Excel)
    将Matlab中的矩阵输出到txt文件
    SQL中对于两个不同的表中的属性取差集except运算
    SQL中union运算操作的理解
    SQL笔记----在一个关系表中操作列
    MathType的公式在word中跟文字不对齐
    开发android过程中eclipse闪退解决
  • 原文地址:https://www.cnblogs.com/whitelily/p/13333828.html
Copyright © 2011-2022 走看看