Codeforces Round 877 (Div. 2) E

E. Count Supersequences

You are given an array aa of n n n integers, where all elements a i a_i ai lie in the range [ 1 , k ] [1,k] [1,k]. How many different arrays b b b of m m m integers, where all elements b i b_i bi lie in the range [ 1 , k ] [1,k] [1,k], contain a a a as a subsequence?

A sequence x x x is a subsequence of a sequence y y y if x x x can be obtained from y y y by the deletion of several (possibly, zero or all) elements.

n , m , k ( 1 ≤ n ≤ 2 ⋅ 1 0 5 , n ≤ m ≤ 1 0 9 , 1 ≤ k ≤ 1 0 9 ) n,m,k(1 \le n \le 2 \cdot 10^5,n \le m \le 10^9,1\le k \le 10^9) n,m,k(1n2105,nm109,1k109)

题意

给你一个长度为 n n n数组 a a a,数字从 1 − k 1-k 1k中选,让你求以 a a a为子序列的长度为 m m m的数组 b b b的个数, b b b数组同样从 1 − k 1-k 1k中选。

思路

首先我们定义 d p i , j dp_{i, j} dpi,j为长度为 i i i,已经匹配了 a a a的前 j j j个字母的方案数

如果第 i i i位选则 d p i , j + = d p i − 1 , j − 1 dp_{i, j} += dp_{i-1,j-1} dpi,j+=dpi1,j1;

如果第 i i i位不选,则
d p i , j = { d p i − 1 , j ∗ ( k − 1 ) , i ! = n d p i − 1 , j ∗ k i = = n dp_{i,j} = \begin{cases} dp_{i-1,j} * (k - 1), & i != n\\ dp_{i-1,j} * k & i == n\\ \end{cases} dpi,j={dpi1,j(k1),dpi1,jki!=ni==n
这样可以解决 m m m 1 e 6 1e6 1e6以下的问题,但是如果 m = 1 e 9 m=1e9 m=1e9,就需要优化,首先我们通过观察原式发现与 a i {a_i} ai没有关系,那我们就将所有数设置成 1 1 1,问题就转化成了从 m m m个数里面挑 n n n个一样的数的方案数,那正着求比较难求,我们考虑容斥,用总方案数减去不符合的 n − 1 n-1 n1 1 1 1的方案数

答案就是 k m − ∑ i = 0 n − 1 ( m i ) ∗ ( k − 1 ) m − i k^m - \sum_{i=0}^{n-1} {m \choose i} *(k - 1)^{m - i} kmi=0n1(im)(k1)mi

那如何快速求 ( m i ) m \choose i (im) 呢?

( m 0 ) = 1 {m\choose0} = 1 (0m)=1

( m i ) = m ( m − 1 ) . . . ( m − i + 1 ) i ( i − 1 ) . . . 1 = m − i + 1 i ( m i − 1 ) i > 1 {m\choose i} = \frac{m(m-1)...(m-i+1)}{i(i-1)...1}= \frac{m - i + 1}{i}{m\choose {i-1}} \quad i > 1 (im)=i(i1)...1m(m1)...(mi+1)=imi+1(i1m)i>1

C[0] = 1;
for(int i = 1; i <= n; i ++){
	C[i] = C[i - 1] * (m - i + 1LL) % MOD * qmi(i, MOD - 2, MOD) % MOD;
}
int ans = qmi(K, m, MOD);
for(int i = 0; i < n; i ++){
	ans = ((ans - C[i] * qmi(K - 1, m - i, MOD) % MOD) % MOD + MOD) % MOD;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值