Count The Blocks

Posted lifehappiness

tags:

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

Count The Blocks

Count The Blocks 题目链接

思路

首先打表出来,发现了一个规律 (num[1] = 10, num[2] = 180),这里的数组标记是反的

发现假定前 (n - 1)个num已经求得,我们可以得到

(num[n] = n * 10^{n} - sum limits ^{n - 1} _{i = 1}(num[n - i] * (i + 1)))

通过对上面的带入,我们可以求得 (num[3] = 3000 - (num[2] * 2 + num[1] * 3) = 2610)

于是我们貌似得到了一个(O(n^2))的算法,想想能不能优化。

我们定义一个sum变量,其中记录的是(sum limits ^{n - 1} _{i = 1} num[i] * (n - i))

再开一个前缀和数组,(a[i] = sumlimits ^{i} _{k = 1}num[k]),接下来我们每次的操作就可以变成线性的来更新sum变量,也就是(sum limits ^{n - 1} _{i = 1}(num[n - i] * (i + 1)))一坨东西。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 998244353;
const int N = 2e5 + 10;

ll num[N], a[N];

ll quick_pow(ll x, ll n) {
    ll ans = 1;
    while(n) {
        if(n & 1)   ans = (ans * x) % mod;
        n >>= 1;
        x = (x * x) % mod;
    }
    return ans;
}
int main() {
    int n;
    scanf("%d", &n);
    num[1] = 10; a[1] = 10;
    ll sum = 10;
    for(int i = 2; i <= n; i++) {
        sum += a[i - 1];
        num[i] = (((quick_pow(10, i) * i) % mod - sum ) % mod + mod) % mod;
        a[i] = (a[i - 1] + num[i]) % mod;
        sum = (sum + num[i]) % mod;
    }
    for(int i = n; i > 0; i--)
        printf("%lld ", num[i]);
    puts("");
    return 0;
}

以上是关于Count The Blocks的主要内容,如果未能解决你的问题,请参考以下文章

E. Count The Blocks

Codeforces 1327 E. Count The Blocks

E. Count The Blocks(找数学规律)

Codeforces 1327E - Count The Blocks (dp)

ACM题目————The Blocks Problem

EOJ 1501 The Blocks Problem