E. Count The Blocks
Posted echozqn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了E. Count The Blocks相关的知识,希望对你有一定的参考价值。
E. Count The Blocks
这是一个计数题,又把我卡自闭了。。。之前也碰到过类似的题目,这次居然还没有写出来,感觉自己还是太菜了,加油补题吧。
题目大意:
给你一个数字 (n),代表的是数的长度,该数可以有前导零,定义连续相同的数可以组成一个块,如果有 (x) 个连续相同的数,则认为这个块大小是 (x)。
问:有n个数字的这个数,可以组成大小为 (i) 的块的数量是多少。
答案输出一行 (n) 个数,第 (i) 个数表示大小为 (i) 的块的数量。
题解:
这种题目就很容易把自己绕进去,所以我们不要每一个去仔细推,而是思考:我要构造大小为 (i) 的块,应该如何去构造。
是不是选一块大小为 (i) 的块,然后这个块如果在中间,则两边的数字应该不同,其他的块则无所谓,如果在边界,则只要满足一边的数字和这个块不同即可,然后统计答案。
这个会不会出现重复呢?或者会不会少统计了呢?
这两个看起来有矛盾的提问,其实就解决了这两个问题。
因为我每一个位置只统计了一次,但是可能我假设的这个位置出现大小为 (i) 的块不止一个,所以才会有疑问会不会少统计了。
同时因为每一个位置都统计了一次,所以可能会有两个位置,出现大小为 (i) 的块的数量及位置都相同,所以才会有疑问会不会重复统计了。
确实有可能会出现 (x) 个位置,此时出现大小为 (i) 的块的数量及位置都相同,但是每一次我只统计了一次,并没有乘以 (x) 这个数,所以不会重复,也不会丢掉一些数。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn=2e5+10;
const int mod=998244353;
typedef long long ll;
ll dp[maxn];
ll binpow(ll x,ll n){
ll ans=1;
while(n){
if(n&1) ans=(ans*x)%mod;
x=(x*x)%mod;
n>>=1;
}
return ans;
}
int main(){
int n;
scanf("%d",&n);
dp[n]=10,dp[n-1]=180;
for(int i=n-2;i>=1;i--){
dp[i]=10*9*binpow(10,n-i-1)%mod*2%mod;
// printf("dp[%d]=%lld
",i,dp[i]);
}
for(int i=n-2;i>=1;i--){
dp[i]=(dp[i]+10*9*9*binpow(10,n-i-2)%mod*(n-i-1)%mod)%mod;
}
for(int i=1;i<=n;i++) printf("%lld ",dp[i]);
return 0;
}
以上是关于E. Count The Blocks的主要内容,如果未能解决你的问题,请参考以下文章
Count The Blocks CodeForces - 1327E oeis
Codeforces 1327E - Count The Blocks (dp)
矩阵乘法&&dp加速矩阵的思路(E. Wet Shark and Blocks)
Codeforces Round #341 (Div. 2) E. Wet Shark and Blocks(矩阵优化DP)