Combinatorics
Description
Given an array \ (a[]\), define an operation:
$
S_i=\sum_{j=1}^{n}{a_j},\
S_i\rightarrow a_i.$
Calculate the value of each \ (a\) after \ (k\) times of operations.
Solution
The official tutorial wrote confusingly, so does other solutions on the Internet.
Calculate how element \ (a_j\) would affects \ (a_i\) \ ((j \le i) \), after \ (k\) times.
Let ' s draw something first.
\ ((i,j,k) \,\text{means}\, I \cdot a_1 + j \cdot a_2 + k \cdot a_3,\ \text{and}\,k \,\text{is times of Operation}:\)
\ (\begin{cases} (1,0,0) \, (1,1,0) \, (1,1,1) \quad \text{where K = 1,}\\ (1,0,0) \, (2,1,0) \, (3,2,1) \quad \text{where K = 2, }\\ (1,0,0) \, (3,1,0) \, (6,3,1) \quad \text{where K = 3},\\ \cdots \end{cases}\)
We also have another graph:
$
\begin{align}
1,1\
1,2,1\
1,3,3,1\
1,4,6,4,1\
\cdots
\end{align}
$
**cnblogs cannot start a new line in Mathjax ...
Think when \ (k\) was changing, how the factor before \ (a_j\) in \ (a_i\) follows, we get:
\[fac_{i,j}^{k} = {j-i+k-1 \choose j-i}\]
To simplify our calculation, we found that \ (fac_{i,j}^{k} = fac_{i-j+1,1}^{k}\), for we can replace \ (j-i\) /c1> with \ (j-i+1-1\), they is the same!
So our tasks now are to calculate \ (fac_{i,1}^{k}\), which is \ (i + k-2 \choose i-1\). But we cannot pre process the factorial of \ (k\), as \ (k\) can is up to \ (10^9\). But \ (fac_{1,1}\) are always 1!
Think the transfer between \ (fac_{i-1,1}\) and \ (fac_{i,1}\), that is:
\[\frac{(i-1+k-2)!} {(I-1-1)! (K-1)!} \rightarrow \frac{(i+k-2)!} {(I-1)! (K-1)!} \]
We just need to multiply the first expression by \ (i+k-2\) and \ ((i-1) ^{-1}\, (mod\,10^9+7) \). And we can pre process all factors in \ (O (n) \) time.
Then finish all calculation in \ (O (n^2) \) time, as\ (\begin{align}s_i=\sum_{j=1}^{i}{f_{i-j+1}\times a_j}\ end{align}\).
Code
#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>using namespace std;typedef long long ll;const ll p = 1e+9 + 7;const int maxn = 2005;int n, k;ll inv[maxn], a[maxn], c[maxn], s[maxn];void init() { inv[1] = 1; for (int i = 2; i <= 2000; ++i) { inv[i] = (-(p/i) + p) * inv[p % i] % p; }}int main() { init(); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> k; for (int i = 1; i <= n; ++i) cin >> a[i]; if(!k) { for(int i = 1; i <= n; ++i) s[i] = a[i]; } else { c[1] = 1; for (int i = 2; i <= n; ++i) c[i] = c[i - 1] * (k + i - 2) % p * inv[i - 1] % p; for (int i = 1; i <= n; ++i) for (int j = 1; j <= i; ++j) s[i] = (s[i] + c[i - j + 1] * a[j] % p) % p; } for (int i = 1; i <= n; ++i) cout << s[i] << " "; cout << endl; return 0;}
Codeforces 223 C