zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    数据量你造吗-JAVA分页
    编写高质量代码改善java程序的151个建议——[1-3]基础?亦是基础
    概率论快速学习03:概率公理补充
    概率论快速学习02:概率公理
    项目ITP(六) spring4.0 整合 Quartz 实现动态任务调度
    项目ITP(五) spring4.0 整合 Quartz 实现任务调度
    编写高质量代码改善java程序的151个建议——导航开篇
    概率论快速学习01:计数
    改善JAVA代码01:考虑静态工厂方法代替构造器
    Python快速学习10: 循环的对象及设计 (生活的规律)
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9844627.html
Copyright © 2011-2022 走看看