zoukankan      html  css  js  c++  java
  • [树状数组] Codeforces 1406D Three Sequences

    题目大意

    给定一个序列 (a_1,a_2,dots,a_n),要求构造出长度为 (n) 的序列 ({b_n},{c_n}),满足 (a_i=b_i+c_i),并且 ({b_n}) 是不下降序列,({c_n}) 是不上升序列。有 (q) 次操作,每次操作可以把 ([l,r]) 的数增加 (x),求每次操作后最小的 (max{b_i,c_i})
    ((n,qleq 10^5))

    题解

    考虑构造 ({a_n},{b_n},{c_n}) 的差分序列 (Delta a_i=a_{i+1}-a_i,Delta b_i=b_{i+1}-b_i,Delta c_i=c_{i+1}-c_i),那么有 (Delta b_igeq 0,Delta c_ileq 0,Delta a_i=Delta b_i+Delta c_i)

    因为要最小化 (max{b_i,c_i}),当 (Delta a_i>0) 时,令 (Delta b_i=Delta a_i,Delta c_i=0)。当 (Delta a_ileq 0) 时,令 (Delta b_i=0,Delta c_i=Delta a_i)。显然这样是最优的,因为当 (Delta a_i>0) 时,若 (Delta b_i<Delta a_i),则 (Delta c_i>0),不满足;若 (Delta b_i>Delta a_i),则 (Delta c_i<0),此时比 (Delta b_i=Delta a_i) 更劣。

    那么假设我们已经确定了 (b_1)(c_1),则 (b_n=b_1+sum_{i=1}^{n-1}Delta b_i)。因为 ({b_n}) 不降, ({c_n}) 不升,所以 (max{b_i,c_i}=max{b_n,c_1}=max{b_1+sum_{i=1}^{n-1}Delta b_i,c_1})。我们肯定是希望 (b_n)(c_1) 越接近越好,因为 (sum_{i=1}^{n-1} Delta b_i) 是固定的,所以我们可以通过将 ({b_n})({c_n}) 分别整体平移来使得 (b_n)(c_1) 更接近,所以 (max{b_i,c_i}=leftlceil frac{b_n+c_1}{2} ight ceil=leftlceil frac{b_1+sum_{i=1}^{n-1}Delta b_i+c_1}{2} ight ceil=leftlceil frac{a_1+sum_{i=1}^{n-1}Delta b_i}{2} ight ceil)

    对于 (sum_{i=1}^{n-1}Delta b_i),我们可以通过预处理求出,对于将区间 ([l,r]) 加上 (x),因为我们做了差分,只需要修改左右两个端点对 (Delta b_i) 造成的影响即可,然后还要求每次修改后的 (sum_{i=1}^{n-1}Delta b_i),于是可以使用树状数组来维护,时间复杂度 (O(n log n))

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    #define RG register int
    #define LL long long
    
    template<typename elemType>
    inline void Read(elemType &T){
        elemType X=0,w=0; char ch=0;
        while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
        while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        T=(w?-X:X);
    }
    
    inline int lowbit(int x){return x&(-x);}
    
    LL a[100010],Delta[100010];
    struct BIT{
        LL Node[100010];
        int N;
        void set_Len(int len){N=len;}
        void Update(int x,LL Add){for(;x<=N;x+=lowbit(x)) Node[x]+=Add;}
        LL PrefixSum(int x){LL Res=0;for(;x;x-=lowbit(x)) Res+=Node[x];return Res;}
        LL Query(int L,int R){return PrefixSum(R)-PrefixSum(L-1);}
        LL GetAns(){
            LL Res=a[1]+PrefixSum(N);
            return (Res&1)?((Res>>1)+1):(Res>>1);
        }
    };
    BIT Tree;
    int N,M;
    
    int main(){
        Read(N);
        Tree.set_Len(N-1);
        for(RG i=1;i<=N;++i)
            Read(a[i]);
        for(RG i=1;i<N;++i){
            if(a[i+1]-a[i]>0) Tree.Update(i,a[i+1]-a[i]);
            Delta[i]=a[i+1]-a[i];
        }
        printf("%I64d
    ",Tree.GetAns());
        Read(M);
        while(M--){
            int L,R;LL Add;
            Read(L);Read(R);Read(Add);
            if(L==1) a[1]+=Add;
            if(L>1){
                Delta[L-1]+=Add;
                Tree.Update(L-1,-Tree.Query(L-1,L-1));
                if(Delta[L-1]>0) Tree.Update(L-1,Delta[L-1]);  
            }
            if(R<N){
                Delta[R]-=Add;
                Tree.Update(R,-Tree.Query(R,R));
                if(Delta[R]>0) Tree.Update(R,Delta[R]);  
            }
            printf("%I64d
    ",Tree.GetAns());
        }
        return 0;
    }
    
  • 相关阅读:
    MySQL + Atlas --- 部署读写分离(实现,其他的技术有参考文档)
    基于Redis、Storm的实时数据查询实践
    Redis 配置
    Redis 安装
    redis简介
    Java-Enumeration总结
    spring源码剖析(四)自定义标签解析流程
    svn 把主干合到分支 分支合到主干
    关于Class.getResource和ClassLoader.getResource的路径问题
    instanceof, isinstance,isAssignableFrom的区别
  • 原文地址:https://www.cnblogs.com/AEMShana/p/13896255.html
Copyright © 2011-2022 走看看