题解 P6595 【[YsOI2020]计划】
大家好,我是队爷 Imakf,这道题我考场上有细节挂了,然而这与 Imakf 强没有任何关系,请大家支持 Imakf,一起喊 Imakf 666!
然而并不是官方题解(虽然我是队爷Imakf)
首先很多的小朋友没有意义,把没被小朋友吃掉的概率乘起来得到每天小饼干活下来的概率
然后
然后问题变为有
第一问是计算 B 期望吃多少个,我们考虑前 T 天期望剩余多少个然后计算答案即可,第
第二问是计算期望多少天吃完,我们视为最晚被吃掉的饼干,那么根据
注意到饼干没有区别,所以我们枚举集合大小即可:
即我们需要计算集合 T 中最早被吃掉的饼干的期望时间,平凡的 trick 是认为是
注意到贡献分为两端,对于
加起来,直接计算即可啦~
如果觉得推得烦了可以看一下代码,emmm确实有点细节吧
#include<bits/stdc++.h>
using namespace std ;
#define Next( i, x ) for( register int i = head[x]; i; i = e[i].next )
#define rep( i, s, t ) for( register int i = (s); i <= (t); ++ i )
#define drep( i, s, t ) for( register int i = (t); i >= (s); -- i )
#define re register
#define int long long
int gi() {
char cc = getchar() ; int cn = 0, flus = 1 ;
while( cc < '0' || cc > '9' ) { if( cc == '-' ) flus = - flus ; cc = getchar() ; }
while( cc >= '0' && cc <= '9' ) cn = cn * 10 + cc - '0', cc = getchar() ;
return cn * flus ;
}
const int N = 2e6 + 5 ;
const int P = 998244353 ;
int n, m, T, p, q, fac[N], inv[N] ;
int fpow( int x, int k ) {
int ans = 1, base = x ;
while( k ) {
if( k & 1 ) ans = ans * base % P ;
base = base * base % P, k >>= 1 ;
} return ans ;
}
int C( int x, int y ) {
if( y > x ) return 0 ;
return fac[x] * inv[y] % P * inv[x - y] % P ;
}
signed main()
{
n = gi(), m = gi(), T = gi() ;
p = gi() ; int x ; q = 1 ;
rep( i, 1, m ) x = gi(), q = q * ( 1 - x + P ) % P ;
if( ( q == 0 ) && ( T != 0 ) ) {
puts("0 1") ; exit(0) ;
}
int Tk = fpow( q, T ) * n % P ;
int ans1 = 0, ans2 = 0 ;
int u = ( 1 - p + P ) * q % P ;
if( p == 1 ) ans1 = Tk ;
else {
ans1 = ( Tk * p ) % P * fpow( 1 - u + P, P - 2 ) % P ;
}
inv[0] = fac[0] = 1 ;
rep( i, 1, n ) fac[i] = fac[i - 1] * i % P, inv[i] = fpow( fac[i], P - 2 ) ;
for( re int k = 1; k <= n; ++ k ) {
int rp = C( n, k ) ;
if( ( k + 1 ) & 1 ) rp = ( P - rp ) % P ;
int tk = fpow( q, k ) ;
int mS = fpow( tk, T ) ;
int fk = fpow( u, k ) ;
int S1 = 1 ;
if( T ) {
S1 = ( ( 1 - fpow( tk, T + 1 ) + P ) % P ) * fpow( 1 - tk + P, P - 2 ) % P ;
}
int S2 = mS * fpow( 1 - fk + P, P - 2 ) % P * fk % P ;
S1 = ( S1 + S2 ) % P ;
ans2 = ( ans2 + S1 * rp % P ) % P ;
}
ans1 %= P, ans2 %= P ;
printf("%lld %lld\n", ans1, ans2 ) ;
return 0 ;
}