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 ( 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 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;
}