zoukankan      html  css  js  c++  java
  • [codeforces/gym/101350/L]维护“凸包”

    题目链接:http://codeforces.com/gym/101350/problems

    给定n个墙,每个墙有一个高度,要支持动态修改墙的高度和查询这个“容器”能盛多少水。

    (队友)观察发现,能盛的水的体积就等于这个容器的“凸包”的体积减去墙的体积。所以要做的就是动态的维护凸包。

    由于只有墙上升的操作,所以只需要用一个区间覆盖区间求和的线段树维护每个位置的凸包上界就可以了。

    维护凸包的关键在于最大值的位置,具体见代码。

    #include<bits/stdc++.h>
    using namespace std;
    #define lson (i<<1)
    #define rson (i<<1|1)
    
    const int maxn=100005;
    long long tree[maxn<<2];
    int n;
    int val[maxn];
    int lz[maxn];
    int len[maxn];
    
    void push_up(int i)
    {
        tree[i]=tree[lson]+tree[rson];
    }
    
    void push_down(int i)
    {
        if (!lz[i]) return;
        lz[lson]=lz[i];
        lz[rson]=lz[i];
        tree[lson]=1ll*lz[i]*len[lson];
        tree[rson]=1ll*lz[i]*len[rson];
        lz[i]=0;
    }
    
    void build(int l,int r,int i=1)
    {
        lz[i]=0;
        if (l==r)
        {
            tree[i]=val[l];
            len[i]=1;
        }
        else
        {
            int mid=(l+r)/2;
            build(l,mid,lson);
            build(mid+1,r,rson);
            push_up(i);
            len[i]=len[lson]+len[rson];
        }
    }
    
    void setval(int l,int r,int x,int nowl,int nowr,int i=1)
    {
        if (l==nowl&&r==nowr)
        {
            lz[i]=x;
            tree[i]=1ll*x*len[i];
        }
        else
        {
            push_down(i);
            int mid=(nowl+nowr)/2;
            if (r<=mid) setval(l,r,x,nowl,mid,lson);
            else if (l>mid) setval(l,r,x,mid+1,r,rson);
            else
            {
                setval(l,mid,x,nowl,mid,lson);
                setval(mid+1,r,x,mid+1,nowr,rson);
            }
            push_up(i);
        }
    }
    
    long long query(int l,int r,int nowl,int nowr,int i=1)
    {
        if (lz[i]) return 1ll*(r-l+1)*lz[i];
        if (l==nowl&&r==nowr) return tree[i];
        else
        {
            int mid=(nowl+nowr)/2;
            if (r<=mid) return query(l,r,nowl,mid,lson);
            else if (l>mid) return query(l,r,mid+1,nowr,rson);
            else return query(l,mid,nowl,mid,lson)+query(mid+1,r,mid+1,nowr,rson);
        }
    }
    
    int a[maxn];
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while (T--)
        {
            int n,q;
            scanf("%d%d",&n,&q);
            for (int i=1;i<=n;i++) scanf("%d",&a[i]);
            long long sum=0;
            for (int i=1;i<=n;i++) sum+=a[i];
            int ma=-1,maj=-1;
            for (int i=1;i<=n;i++) if (a[i]>ma) ma=a[i],maj=i;
            int nowma=-1;
            for (int i=1;i<=maj;i++)
            {
                nowma=max(nowma,a[i]);
                val[i]=nowma;
            }
            nowma=-1;
            for (int i=n;i>=maj;i--)
            {
                nowma=max(nowma,a[i]);
                val[i]=nowma;
            }
            build(1,n);
            while (q--)
            {
                char op[5];
                scanf("%s",op);
                if (op[0]=='P')
                {
                    printf("%I64d
    ",tree[1]-sum);
                }
                else
                {
                    int id,h;
                    scanf("%d%d",&id,&h);
                    sum+=h;
                    a[id]+=h;
                    if (query(id,id,1,n)<a[id])
                    {
                        if (id==maj)
                        {
                            setval(id,id,a[id],1,n);
                        }
                        else if (id<maj)
                        {
                            if (a[id]<=a[maj]) setval(id,maj-1,a[id],1,n);
                            else
                            {
                                setval(id+1,maj,a[maj],1,n);
                                setval(id,id,a[id],1,n);
                                maj=id;
                            }
                        }
                        else
                        {
                            if (a[id]<=a[maj]) setval(maj+1,id,a[id],1,n);
                            else
                            {
                                setval(maj,id-1,a[maj],1,n);
                                setval(id,id,a[id],1,n);
                                maj=id;
                            }
                        }
                    }
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    20145201 《Java程序设计》第一周学习总结
    调查问卷
    Hello Java
    Java学习——开端
    java,我准备好了
    20145229吴姗珊 《Java程序设计》第4周学习总结
    20145229吴姗珊 《Java程序设计》第3周学习总结
    20145229吴姗珊《Java程序设计》第二周学习总结
    20145229吴姗珊《JAVA程序设计》第一周学习总结
    20145207 《信息安全系统设计基础》期中总结
  • 原文地址:https://www.cnblogs.com/acmsong/p/7718300.html
Copyright © 2011-2022 走看看