ARC-114 C- Sequence Scores 计数
ARC-114 C- Sequence Scores 计数
题意
给定长度为\(n\)的可重数列\(A\),\(A\)中元素的范围是\(1-M\)。
给定长度为\(n\)的可重数列\(X\),初始时刻元素全部为\(0\)
每次可以进行操作\([l,r,x]\)对数列\(X\)的\([l,r]\)区间\([l,r]\)取操作\(max(v,x[i])\)
记某可重数列\(A(w)\)最少经过\(c\)次操作可以得到\(X\)
问\(\sum c_{A_(i)}\) ,\(A(i)\)为所有可能的可重数列
\[1\leq n,m\leq5000
\]
分析
动态地认为每次向已经存在的\(A\)中加入一个数来记录答案。
假设当前加入的数为\(x\)
- 若\(x\)不在\(A\)中出现,\(c++\),因为必须花费一次来得到这个数
- 若\(x\)在\(A\)中出现过,\(x_{pre}\)到\(x\)之间的所有数都大于\(x\),这样不需要额外花费1,因为可以一次性得到这些\(x\)
- 若\(x\)在\(A\)中出现过,\(x_{pre}\)到\(x\)之间不是所有数都大于\(x\),那么必然要额外花费1
因此新加入的数带来的贡献全部由1和3组成,记贡献为\(S_{i,x}\)
\[S_{i,x} = m^{i - 1} - \sum_{k = 1}^{i - 1}(m - x)^{i - 1 - k}\times m^{k - 1}
\]
其中\(k\)表示出现\(x\)的位置,那么\([k,i - 1]\)之间的所有数取值范围是\([x + 1,m]\)。其他地方数任意取即可。
\[ans_i = \sum_{x = 1}^{m} ans_{i - 1} + S_{i,x}
\]
复杂度\(O(nm)\)
其中\(\sum_{k}\)的和式可以用前缀和递推
代码
int main(){
int n = rd();
int m = rd();
vector<ll> sum(m + 1,1);
ll ans = m;
ll pre = 0;
vector<ll> pow(n + 1);
pow[0] = 1;
for(int i = 1;i <= n;i++)
pow[i] = (ll)pow[i - 1] * m,pow[i] %= MOD;
for(int i = 2;i <= n;i++){
pre = ans;
ans = 0;
if(i > 2) {
for(int j = 1;j <= m;j++)
sum[j] = (ll) sum[j] * (m - j) % MOD + pow[i - 2],sum[j] %= MOD;
}
for(int j = 1;j <= m;j++)
ans += ((ll)pre + pow[i - 1] - sum[j] + MOD) % MOD,ans %= MOD;
}
cout << ans;
}