AGC:Removing Blocks(计数)

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 Ai. 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 ( xy ) are connected when, for all z ( xzy ), 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 109+7.

Constraints

  • 1≤N≤105
  • 1≤Ai≤109
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A1 A2 … AN

Output

For all of the N! orders, find the total cost of the N operations, and print the sum of those N! total costs, modulo 109+7.


Sample Input 1

Copy

2
1 2

Sample Output 1

Copy

9

First, we will consider the order "Block 1 -> Block 2". In the first operation, the cost of the operation is 1+2=3, as Block 1 and 2 are connected. In the second operation, the cost of the operation is 2, as only Block 2 remains. Thus, the total cost of the two operations for this order is 3+2=5.

Then, we will consider the order "Block 2 -> Block 1". In the first operation, the cost of the operation is 1+2=3, as Block 1 and 2 are connected. In the second operation, the cost of the operation is 1, as only Block 1 remains. Thus, the total cost of the two operations for this order is 3+1=4.

Therefore, the answer is 5+4=9.


Sample Input 2

Copy

4
1 1 1 1

Sample Output 2

Copy

212

Sample Input 3

Copy

10
1 2 4 8 16 32 64 128 256 512

Sample Output 3

Copy

880971923

题意:N个带权砖块,依此拿掉其中一个,每次拿的花费为当前砖块所在连通块的权值之和,问所有N!种拿法的总花费。

思路:考虑每个转块的值对答案的贡献,比如第j个砖块,假设它在拿走第i个(i<j)砖块的时候作出贡献,计算一下方案数:先设len=j-i+1(该区间长度),显然拿走i的时候[i+1,j]都必须还在,那么在一个操作序列里面,对于[i,j]的方案数为(len-1)!,剩下的数随意插进去,根据隔板法,剩余的数的方案数为(len+1)*(len+2)*(len+3)*......*n,那么对于这个i,总的方案数即为n!*(1/len)乘上j的权值,也就是拿走第i个(i<j)砖块的时候j能够作出的总贡献了。预处理下逆元的前缀和,总复杂度O(n)。

# include <cstdio>
const long long mod = 1e9+7;
long long inv[100003]={1,1}, fi[100003]={1,1};
int main(){
    int n;
    long long ans = 0, b=1, x;
    scanf("%d",&n);
    for(int i=2; i<=n; ++i){
        inv[i] = inv[mod%i]*(mod-mod/i)%mod;
        fi[i] = (fi[i-1]+inv[i])%mod;
    }
    for(int i=1; i<=n; ++i){
        scanf("%lld",&x);
        ans = (ans + (fi[i]+fi[n-i+1]-1+mod)%mod*x%mod)%mod;
        b = b*i%mod;
    }
    printf("%lld\n",ans*b%mod);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值