• icpc2018徐州OnlineG-Trace(线段树)


    传送门

    首先计算宽度,维护一棵线段树存之前扫描过的线段中时间比当前边大的长度

    于是可以线段树下标为时间,值为长度,因为线段树要做到子节点的信息能往上传。如果下标为长度,值为时间,我们就不能动态地计算时间大于 t 时的长度!

    ac代码:

    #include<bits/stdc++.h>
    #define per(i,a,b) for(int i=a;i<=b;i++)
    #define mod 1000000007
    using namespace std;
    typedef long long ll;
    //#define int long long
    const int inf =0x3f3f3f3f;
    const double eps=1e-8;
    int read(){
        char ch=getchar();
        int res=0,f=0;
        while(ch<'0' || ch>'9'){f=(ch=='-'?-1:1);ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+(ch-'0');ch=getchar();}
        return res*f;
    }
    // ------------------------head
    const int siz=5e4+5;
    int n;
    int tr[siz*4];//维护一棵时间线段树来存某时间前的长度
    struct Node{
        int w,h,t;//w宽度  h高度
    }node[siz];
    bool cmp1(Node a,Node b){return a.h>b.h;}
    bool cmp2(Node a,Node b){return a.w>b.w;}
    int query(int u,int l,int r,int para){
        if(l>=para)return tr[u];
        int mid=l+r>>1;
        if(mid>=para)return max(query(u<<1,l,mid,para),query(u<<1|1,mid+1,r,para));
        else if(mid<para)return query(u<<1|1,mid+1,r,para);
    }
    void update(int u,int l,int r,int t,int v){
        if(l==r){tr[u]=max(tr[u],v);;return;}
        int mid=(l+r>>1);
        if(t<=mid)update(u<<1,l,mid,t,v);
        else if(t>mid)update(u<<1|1,mid+1,r,t,v);
        tr[u]=max(tr[u<<1],tr[u<<1|1]);
    }
    
    signed main()
    {
        scanf("%d",&n);
        memset(tr,0,sizeof(tr));
        per(i,1,n){
            scanf("%d %d",&node[i].w,&node[i].h);
            node[i].t=i;
        }
        ll ans=0;
        sort(node+1,node+n+1,cmp1);
        for(int i=1;i<=n;i++){//按照高度排序,计算宽度
            int num=query(1,1,n,node[i].t);
            if(node[i].w>num){
                ans+=(ll)(node[i].w-num);
            }
            update(1,1,n,node[i].t,node[i].w);
        }
        memset(tr,0,sizeof(tr));
        sort(node+1,node+1+n,cmp2);
        for(int i=1;i<=n;i++){//按照宽度排序,计算高度
            int num=query(1,1,n,node[i].t);//num即按宽降序(前面的宽度都是更大的)后,前面出现的线段中高度最高的
            if(node[i].h>num)ans+=(ll)(node[i].h-num);
            update(1,1,n,node[i].t,node[i].h);
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    学习C#泛型
    css半透明渐变过渡效果
    CSS Grid布局
    CSS writing-mode属性
    单点登录原理与简单实现
    linux磁盘挂载
    Fiddler抓包工具学习
    javascript事件机制之冒泡、捕获、传播、委托
    HTML行内元素、块状元素、行内块状元素的区别
    console.log详细介绍
  • 原文地址:https://www.cnblogs.com/WindFreedom/p/9637255.html
Copyright © 2020-2023  润新知