• H Happy Triangle(询问是否构成三角形)


    题:https://ac.nowcoder.com/acm/contest/5667/H

    题意:给定空的容器multiset:MS,有q个操作,操作一为向MS中加入x,操作二为在MS删除x,操作三为询问在MS是否存在a,b与x能形成一个不退化的三角形。

    分析:对于询问操作,有俩种情况,情况一是x作为最大边,这种情况只要判断在MS中小于等于x的最大的俩个数来判断能否形成三角形,用一个set容器即可搞定;

       情况二为x不作为最大边,假设有a<=b满足条件,因为这种情况b肯定比x大,而a在越接近于b的情况下,x,a,b更容易满足条件,转化为b-a越小越能满足条件,所以这中情况,只要找x后缀中与前驱a之差最小的值ans,若ans<x说明存在,否则不存在,这部分可以用线段树解决。

       而操作一和操作二根据线段树值的确立来进行相应的操作即可。

       (记得开ll)

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    #define MP make_pair
    #define lson root<<1,l,midd
    #define rson root<<1|1,midd+1,r
    typedef long long ll;
    const int mod=1e9+7;
    const int M=2e5+5;
    const ll inf=1e18;
    ll tr[M<<2],lisan[M],cnt[M],a[M],op[M],m;
    multiset<ll>MS;
    void pn(){
        puts("No");
    }
    void py(){
        puts("Yes");
    }
    void up(int root){
        tr[root]=min(tr[root<<1],tr[root<<1|1]);
    }
    void build(int root,int l,int r){
        tr[root]=inf;
        ///cout<<l<<" "<<r<<endl;
        if(l==r)
            return ;
        int midd=(l+r)>>1;
        build(lson);
        build(rson);
    }
    void update(int pos,ll c,int root,int l,int r){
        if(l==r){
            tr[root]=c;
            return ;
        }
        int midd=(l+r)>>1;
        if(pos<=midd)
            update(pos,c,lson);
        else
            update(pos,c,rson);
        up(root);
    }
    ll query(int L,int R,int root,int l,int r){
        if(L<=l&&r<=R)
            return tr[root];
        int midd=(l+r)>>1;
        ll minn=inf;
        if(L<=midd)
            minn=min(minn,query(L,R,lson));
        if(R>midd)
            minn=min(minn,query(L,R,rson));
        return minn;
    }
    
    void solve1(int x){
        int pos=lower_bound(lisan+1,lisan+1+m,x)-lisan;
        if(cnt[pos]){
            update(pos,0,1,1,m);
        }
        else{
            auto it=MS.lower_bound(x);
            auto tmp=it;
            ///更新当前插入位
            it--;
            update(pos,x-*it,1,1,m);
            ///更新当前插入位的后一位
            int pos2=lower_bound(lisan+1,lisan+1+m,*tmp)-lisan;
            if(cnt[pos2]<2)
                update(pos2,*tmp-x,1,1,m);
        }
        cnt[pos]++;
        MS.insert(x);
    }
    void solve2(int x){
        int pos=lower_bound(lisan+1,lisan+1+m,x)-lisan;
        if(cnt[pos]==2){
            auto it=MS.lower_bound(x);
            it--;
            update(pos,x-*it,1,1,m);
        }
        else if(cnt[pos]==1){
            update(pos,inf,1,1,m);
            auto pre=MS.lower_bound(x);pre--;
            auto las=MS.upper_bound(x);
            int pos2=lower_bound(lisan+1,lisan+1+m,*las)-lisan;
            if(cnt[pos2]<2){
                update(pos2,*las-*pre,1,1,m);
            }
        }
        cnt[pos]--;
        ///因为只删一个,所以不能直接删除
        auto it=MS.lower_bound(x);
        MS.erase(it);
    }
    void solve3(int x){
        ///x作为最大边
        auto it=MS.upper_bound(x);it--;
        if(it!=MS.begin()){
            auto tmp=it;it--;
            if(*tmp+*it>x){
                py();
                return ;
            }
        }
        ///x不作为最大边
        it=MS.upper_bound(x);
        int pos=lower_bound(lisan+1,lisan+1+m,*it)-lisan;
        if(query(pos,m,1,1,m)<x)
            py();
        else
            pn();
        return ;
    }
    int main(){
        int n,tot=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&op[i],&a[i]);
            lisan[++tot]=a[i];
        }
        lisan[++tot]=inf,lisan[++tot]=-inf;
    
        sort(lisan+1,lisan+1+tot);
        m=unique(lisan+1,lisan+1+tot)-lisan-1;
        MS.insert(inf),MS.insert(-inf);
        build(1,1,m);
    
        for(int i=1;i<=n;i++){
            if(op[i]==1)solve1(a[i]);
            else if(op[i]==2)solve2(a[i]);
            else solve3(a[i]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    IDEA中好用的插件
    Win10安装Docker
    win10系统关闭此电脑的文件夹
    postgreSQL主键自增长
    【设计模式】工厂模式
    vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响),转载
    springCloud中的组件学习
    使用springBoot+jsp+redis解决单一用户问题
    使用HtmlUnit动态获取网页数据
    java爬取网站中所有网页的源代码和链接
  • 原文地址:https://www.cnblogs.com/starve/p/13305057.html
Copyright © 2020-2023  润新知