Codeforces 1327E. Count The Blocks(组合计数)

链接:http://codeforces.com/contest/1327/problem/E
来源:Codeforces

Codeforces 1327E. Count The Blocks(组合计数)_第1张图片

  题意:给你一个 n n n,如果 n = 3 n = 3 n=3,那么一个数字的表示形式可以是 000 , 000, 000, 001 , 001, 001, 002 , 002, 002, ⋅ ⋅ ⋅ , ···, , 999 999 999,现在给你一个 n n n,如果是 000 000 000,就算是一个长度为 3 3 3 的一个块,如果是 001 001 001,就有两个块,一个块是长度为 2 2 2 的块,另外一个块是长度为 1 1 1 的块,某一个数字如果连续出现 l e n len len 个,那么就算是长度为 l e n len len 的块,现在给你一个 n n n,在 [ 0 , 1 0 n − 1 ] [0, 10^{n} - 1] [0,10n1],中我们可以找到多少个长度为 i i i 的块。
  思路:如果 n = 1 n = 1 n=1 的时候,那么这一个位置我们可以放 [0, 9] 这 10 个数字, n = 2 n = 2 n=2 的时候,如果 i = = n i == n i==n,那么我们可以发现,我们只能在 10 个数字中选择一个来填充这 n 个位置。如果 i < n i < n i<n 的时候,如果这个长度为 i i i 的块,在这个数字的两端,那么在某一端可以选择 10 10 10 个数字,在一端的旁边我们只能选择 9 9 9 个数字,这样我们就可以保证这个数字中有长度为 i i i 的块,那么剩下的 n − i − 1 n - i - 1 ni1 个位置,每一个位置我们都可以放 10 10 10 个数字,如果在左端是这种情况,那么在右端也将是这种情况,此时这种情况的结果就是 10 ∗ 9 ∗ 1 0 n − i − 1 , n > = i + 1 10 * 9 * 10^{n - i - 1},n >= i + 1 10910ni1,n>=i+1;另外一种情况就是这个长度为 i i i的块在整个数字的中间,中间一共有的数字就是 n − 2 n - 2 n2 个,这 n − 2 n - 2 n2 个位置我们可以组成的满足条件的块就是 n − 2 − i + 1 n - 2 - i + 1 n2i+1 个,每一种情况都是可以选择 10 10 10 个数字,在这个块的两端只能选择 9 9 9 个数字,此时可以构造一个满足条件的块,此时的结果就是 ( n − 2 − i + 1 ) ∗ 10 ∗ 9 ∗ 9 (n - 2 - i + 1) * 10 * 9 * 9 (n2i+1)1099,这个时候还剩下的位置就是 n − i − 2 n - i - 2 ni2 个,这里每一个位置又可以选择 10 10 10 个数字,这种情况下的结果就是 10 ∗ 9 ∗ 9 ∗ ( n − 2 − i + 1 ) ∗ 1 0 n − i − 2 , n > = i + 2 10 * 9 * 9 *(n - 2 - i + 1) * 10^{n - i - 2},n >= i + 2 1099(n2i+1)10ni2,n>=i+2

# include
using namespace std;

typedef long long ll;
const int maxn = 2e5 + 10;
const int mod = 998244353;
int a[maxn];

ll quickPow(ll a, ll b) {
     
    ll ans = 1, res = a;
    while(b) {
     
        if(b & 1) ans = ans * res % mod;
        res = res * res % mod;
        b >>= 1;
    }
    return ans % mod;
}

int main() {
     
    int n; scanf("%d", &n);
    a[n] = 10;
    for(int i = 1; i <= n; ++ i) {
     
        if(n >= i + 1) a[i] = (1ll * 10 * 9 * quickPow(10, n - i - 1) % mod) * 2 % mod; 
        if(n >= i + 2) {
     
            a[i] +=  1ll * 10 * 9 * 9 * (n - 2 - i + 1) * quickPow(10, n - i - 2) % mod;
            a[i] %= mod;
        }
        //cout << i << " " << a[i] << "------------" << endl;
    }
    for(int i = 1; i <= n; ++ i) printf("%d%c", a[i], i == n ? '\n' : ' ');
    return 0;
}

你可能感兴趣的:(Mathematics)