Loading

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;
}
posted @ 2021-03-15 13:51  MQFLLY  阅读(292)  评论(0编辑  收藏  举报