• 【学习笔记】CF1817E Half-sum


    首先最优的贪心策略为:将原数组 排序 后,选择一个分界点 p p p,然后对于 [ 1 , p ] [1,p] [1,p]从后往前合并, [ p + 1 , n ] [p+1,n] [p+1,n]从前往后合并,将前后两个数的差值作为答案。模拟二进制下的加法即可做到 O ( n ) O(n) O(n)检查。注意这里不需要均摊维护高精度加法(这样做会多一个 log ⁡ \log log),因为我们不关心中途的结果。

    然后,从一次复合函数的角度推导(这样形式更为简洁):

    f ( a 1 , . . . , a i , x ) = a x + b f(a_1,...,a_i,x)=ax+b f(a1,...,ai,x)=ax+b,那么 f ( a 1 , . . . , a i , a i + 1 , x ) = a ⋅ a i + 1 + x 2 + b = 1 2 a x + 1 2 a ⋅ a i + 1 + b f(a_1,...,a_i,a_{i+1},x)=a\cdot \frac{a_{i+1}+x}{2}+b=\frac{1}{2}ax+\frac{1}{2}a\cdot a_{i+1}+b f(a1,...,ai,ai+1,x)=a2ai+1+x+b=21ax+21aai+1+b

    注意到 a = 1 2 i a=\frac{1}{2^{i}} a=2i1,因此从增长率的角度来看,应该只选前 30 30 30项和后 30 30 30项进行检查。

    通常,我们可以通过邻项比较(找 变化量)的方法来排除掉一些一定不优的方案。

    发现 f ( a 1 , . . . , a i + 1 ) − f ( a 1 , . . . , a i ) = 1 2 a ⋅ ( a i + 1 − a i ) = 1 2 i ( a i + 1 − a i ) f(a_1,...,a_{i+1})-f(a_1,...,a_i)=\frac{1}{2}a\cdot(a_{i+1}-a_i)=\frac{1}{2^i}(a_{i+1}-a_i) f(a1,...,ai+1)f(a1,...,ai)=21a(ai+1ai)=2i1(ai+1ai),因此考虑原数组的差分数组 d i = a i + 1 − a i d_i=a_{i+1}-a_i di=ai+1ai,那么从方案 i i i j j j的变化量为: − d i 2 i − ∑ i < k < j d k ( 1 2 k − 1 2 n − k ) + d j 2 n − j -\frac{d_i}{2^i}-\sum_{i2idii<k<jdk(2k12nk1)+2njdj

    注意到,如果 d i = 0 d_i=0 di=0那么 i i i一定不会成为最优分界点,因此我们 应该满足 d i > 0 d_i>0 di>0 。那么,当 i ≤ j ≤ n 2 i\le j\le \frac{n}{2} ij2n时,中间的式子一定 ≤ 0 \le 0 0,只有当 n − j ≤ i + 30 n-j\le i+30 nji+30时才可能成为答案。即: j ≥ n − i − 30 j\ge n-i-30 jni30。这样,我们只要找到第一个满足 ≤ n 2 − 30 \le \frac{n}{2}-30 2n30并且 d i > 0 d_i>0 di>0的位置,这一定是最优的;如果不存在,那么检验 [ n 2 − 30 , n 2 ] [\frac{n}{2}-30,\frac{n}{2}] [2n30,2n]中的所有位置。其等价实现是,检验前 30 30 30个满足 d i > 0 d_i>0 di>0的位置。对于 j > n 2 j>\frac{n}{2} j>2n的情况显然是同理的。

    复杂度 O ( n log ⁡ V ) O(n\log V) O(nlogV)

    #include
    #define ll long long
    #define pb push_back
    #define fi first
    #define se second
    #define db double
    #define inf 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int mod=1e9+7;
    const int N=1e6+65;
    int T,n,m,res;
    ll a[N],inv2=(mod+1)/2;
    ll b[N],c[N],r[N];
    void solve(int x){
        for(int i=0;i<=n+60;i++)b[i]=c[i]=0;
        for(int i=x;i>=1;i--){
            int j=i-(i==x);
            b[n-j]+=a[i];
        }for(int i=0;i<=n+60;i++)b[i+1]+=b[i]/2,b[i]%=2;
        for(int i=x+1;i<=n;i++){
            int j=n-i+1-(i==x+1);
            c[n-j]+=a[i];
        }for(int i=0;i<=n+60;i++)c[i+1]+=c[i]/2,c[i]%=2;
        for(int i=0;i<=n+60;i++){
            c[i]-=b[i];if(c[i]<0)c[i]+=2,c[i+1]--;
        }
        int it=n+60;while(it&&c[it]==r[it])it--;
        if(c[it]>r[it]){
            for(int i=0;i<=n+60;i++)r[i]=c[i];
            res=x;
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0),cout.tie(0);
        cin>>T;
        while(T--){
            cin>>n;for(int i=1;i<=n;i++)cin>>a[i];
            sort(a+1,a+1+n);res=1;for(int i=0;i<=n+60;i++)r[i]=0;
            int j=1;
            for(int i=1;i<=30;i++){
                while(j<n&&a[j]==a[j+1])j++;
                if(j==n)break;solve(j),j++;
            }j=n;
            for(int i=1;i<=30;i++){
                while(j>1&&a[j]==a[j-1])j--;
                if(j==1)break;solve(j-1),j--;
            }ll x=a[res];
            for(int i=res-1;i>=1;i--)x=(x+a[i])*inv2%mod;
            ll y=a[res+1];
            for(int i=res+2;i<=n;i++)y=(y+a[i])*inv2%mod;
            cout<<(y-x+mod)%mod<<"\n";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
  • 相关阅读:
    【C】栈和队列
    自动化测试数据生成:Asp.Net Core单元测试利器AutoFixture详解
    Spring Cloud OpenFeign - - - > 契约配置
    java计算机毕业设计装修设计管理系统设计与实现源码+系统+mysql数据库+lw文档+部署
    SpringMVC(三)获取请求参数
    问题越古老,解决方案存在的时间就越长
    【MySQL】MySQL中如何实现分页操作
    Javascript笔记
    三维模型3DTile格式轻量化压缩处理的数据质量提升方法分析
    磁盘管理 及 nfs服务配置
  • 原文地址:https://blog.csdn.net/cqbzlydd/article/details/133276116