• AtCoder Grand Contest 028 B


    B - Removing Blocks

    Time limit : 2sec / Memory limit : 1024MB

    Score : 600 points

    Problem Statement

    There are (N) blocks arranged in a row, numbered 1 to (N) from left to right. Each block has a weight, and the weight of Block (i) is (A_i). Snuke will perform the following operation on these blocks (N) times:

    Choose one block that is still not removed, and remove it. The cost of this operation is the sum of the weights of the blocks that are connected to the block being removed (including itself).

    Here, two blocks (x) and (y) ( (x≤y) ) are (connected) when, for all (z) ( (x≤z≤y) ), Block (z) is still not removed.

    There are (N)! possible orders in which Snuke removes the blocks. For all of those (N)! orders, find the total cost of the (N) operations, and calculate the sum of those (N)! total costs. As the answer can be extremely large, compute the sum modulo (10^9+7).

    Constraints

    • (1≤N≤10^5)

    • (1≤A_i≤10^9)

    • All values in input are integers.


    题意:给你(n)个位置,每个位置有权值(a),随机删去位置上的数,得到的权值是这个位置相连的联通块内的权值和(联通的定义是位置相邻且数没有删去),每次删完,求所有删数方案的权值和。

    发现权值和就是一次删数(指删完整个序列)的权值期望乘上删数方案(n!),于是我们需要求删数的权值期望。

    考虑每个位置的贡献,当位置(i)被删去时,( t{ta})的连通性一共有(n)种可能。

    设删去时的连通块为((i,j)),则在这种情况下删( t{ta})的可能性是(P_{i,j}=frac{1}{|i-j|+1})

    (i)的整个权值贡献为(a_isum_{j=1}^nP_{i,j})

    则答案为

    [fac_nsum_{i=1}^na_isum_{j=1}^nP_{i,j} ]

    发现(p)可以预处理前缀和,枚举一下(i)就可以了


    Code:

    #include <cstdio>
    #define ll long long
    const int N=1e5+10;
    const ll mod=1e9+7;
    int n;
    ll a[N],fac=1,inv[N],ans;
    ll quickpow(ll d,ll k)
    {
        ll f=1;
        while(k)
        {
            if(k&1) f=f*d%mod;
            d=d*d%mod;
            k>>=1;
        }
        return f;
    }
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define dep(i,a,b) for(int i=a;i>=b;i--)
    int main()
    {
        scanf("%d",&n);
        rep(i,1,n) fac=fac*i%mod,inv[i]=quickpow(i,mod-2),scanf("%lld",a+i);
        rep(i,1,n) (inv[i]+=inv[i-1])%=mod;
        rep(i,1,n) (ans+=a[i]*(inv[i]+inv[n-i+1]-1))%=mod;
        printf("%lld
    ",ans*fac%mod);
        return 0;
    }
    

    2018.10.24

  • 相关阅读:
    行转列,列转行
    聚合函数:sum,count,max,avg
    row_number() over partition by 分组聚合
    mysql优化
    hive中not in优化
    DBCP数据库连接池的简单使用
    Eclipse或MyEclipse中给第三方jar包添加源码步骤
    Java中CountDownLatch类的使用
    PLSQL Developer安装、配置、连接oracle数据库
    oracle11g卸载(win10)
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9844627.html
Copyright © 2020-2023  润新知