Codeforces 223 C

Posted nishikino-curtis

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 223 C相关的知识,希望对你有一定的参考价值。

Combinatorics

Description

Given an array (a[]), define an operation:

$
s_i=sum_{j=1}^{n}{a_j},
s_i ightarrow a_i.$

Calculate the value of each (a) after (k) times of operations.

Solution

The official tutorial wrote confusingly, so did other solutions on Internet.

Calculate how element (a_j) will affects (a_i) ((j le i)), after (k) times.

Let‘s draw something first.

((i,j,k), ext{means}, i cdot a_1 + j cdot a_2 + k cdot a_3, ext{and},K , ext{is times of operation}:)

(egin{cases} (1,0,0), (1,1,0), (1,1,1)quad ext{where K = 1,}\ (1,0,0), (2,1,0), (3,2,1)quad ext{where K = 2,}\ (1,0,0), (3,1,0), (6,3,1)quad ext{where K = 3},\ cdots end{cases})

We also have another graph:

$
egin{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) is 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) with (j-i+1-1), they are the same!

So our task now is 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 be up to (10^9). But (fac_{1,1}) is 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)!} ightarrow 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(egin{align}s_i=sum_{j=1}^{i}{f_{i-j+1} imes 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的主要内容,如果未能解决你的问题,请参考以下文章

[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段

交织深度为2的RS(255,223)纠错编码,c#实现有没有代码呀,网上只搜到c++和matlab的

这个c代码有啥问题?

leetcode223

223. Rectangle Area

C 中的共享内存代码片段