首页 > 其他分享 >「CF1392H」ZS Shuffles Cards

「CF1392H」ZS Shuffles Cards

时间:2023-02-19 10:33:11浏览次数:63  
标签:return int CF1392H Shuffles const Mul Cards inline mod

题目

点这里 看题目。


你有 \(n+m\) 张牌,其中有恰好 \(n\) 张为数字牌,分别标有 \(1,2,3,\dots,n\),剩下的恰好 \(m\) 张均为鬼牌。

一开始,牌被随机打乱,同时你有一个集合 \(S=\varnothing\)。接下来,你将要进行如下操作若干轮:

一轮操作中,你需要从牌堆里选出一张牌:

  • 如果是数字牌,假设牌上标有数字 \(x\),则你需要将它从牌堆中取出放到一边,并令 \(S\gets S\cap \{x\}\)。

  • 如果是鬼牌,则将所有的牌放回牌堆并重新洗牌,所以洗完牌后牌堆里仍然有 \(n+m\) 张牌。

    此时,如果 \(S=\{1,2,3,\dots,n\}\),操作结束。否则,\(S\) 不变,你需要继续抽牌。

设 \(X\) 为操作结束时经过的轮数,你需要求出 \(E[x]\bmod 998244353\)。

所有数据满足 \(1\le n,m\le 2\times 10^6\)。

分析

三年前不会做,三年后差点还是不会做。

记 \([n]=\{1,2,3,\dots,n\}\)。将操作过程看作:每次以一定概率取出一个集合 \(T\subseteq [n]\),并令 \(S\gets S\cap T\);如果某次操作完后 \(S=[n]\) 则停止,\(X\) 即为 \(\sum |T|\)。

这个结构让人想到 min-max 反演。设 \(X_k\) 表示编号为 \(k\) 的牌第一次出现在集合 \(S\) 中时,已经出现过的 \(T\) 的大小之和,则 \(X=\max_{1\le k\le n}\{X_k\}\)。对它做反演,我们要求的就是 \(E[\min_{k\in A} X_k](A\subseteq [n],A\neq \varnothing)\)。

答案显然只和 \(|A|\) 有关,所以设 \(s=|A|,E_s=E[\min_{k\in A}X_k]\)。于是,考察每一种大小的集合出现的概率:任意一种大小为 \(k\) 的集合的出现概率为 \(q_k=\frac{n^{\underline k}m}{(n+m)^{\underline{k+1}}}\),任意一种大小为 \(k\) 的不包含 \(A\) 中元素的集合的出现概率为 \(p_k=\frac{(n-s)^{\underline k}m}{(n+m)^{\underline{k+1}}}\)。另设 \(P=\sum_k p_k\),则可以得到:

\[E_s=\sum_{j\ge 0}\sum_k P^j((k+1)p_k+(k+1)(q_k-p_k))=\frac{1}{1-P}\sum_k (k+1)q_k \]

\(\sum_k (k+1)q_k\) 与 \(s\) 无关,所以我们重点考虑求 \(P\)。不妨设 \(r=n-s\),那么有:

\[\begin{aligned} P &=\sum_{k=0}^r\frac{r^{\underline k}m}{(n+m)^{\underline{k+1}}}\\ &=\frac{m}{n+m}\sum_{k=0}^r\frac{\binom{r}{k}}{\binom{n+m-1}{k}}\\ &=\frac{m}{n+m}\sum_{k=0}^r\frac{\binom{n+m-1-k}{r-k}}{\binom{n+m-1}{r}}\\ &=\frac{m}{n+m}\binom{n+m-1}{r}^{-1}\sum_{k=0}^r\binom{n+m-1-k}{n+m-1-r}\\ &=\frac{m}{n+m}\binom{n+m-1}{r}^{-1}\binom{n+m}{n+m-r} \end{aligned} \]

于是就可以 \(O(1)\) 求出来了,于是就可以 \(O(n)\) 计算答案了。

进行后续数学推导也可以得到封闭结果,不过没有必要了。

代码

#include <cstdio>

#define rep( i, a, b ) for( int i = (a) ; i <= (b) ; i ++ )
#define per( i, a, b ) for( int i = (a) ; i >= (b) ; i -- )

const int mod = 998244353, inv2 = ( mod + 1 ) >> 1;
const int MAXN = 4e6 + 5;

template<typename _T>
inline void Read( _T &x ) {
	x = 0; char s = getchar(); bool f = false;
	while( ! ( '0' <= s && s <= '9' ) ) { f = s == '-', s = getchar(); }
	while( '0' <= s && s <= '9' ) { x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar(); }
	if( f ) x = -x;
}

template<typename _T>
inline void Write( _T x ) {
	if( x < 0 ) putchar( '-' ), x = -x;
	if( 9 < x ) Write( x / 10 );
	putchar( x % 10 + '0' );
}

int P[MAXN];
int fac[MAXN], ifac[MAXN], inv[MAXN];

int N, M;

inline int Qkpow( int, int );
inline int Inv( const int &a ) { return Qkpow( a, mod - 2 ); }
inline int Mul( int x, const int &v ) { return 1ll * x * v % mod; }
inline int Sub( int x, const int &v ) { return ( x -= v ) < 0 ? x + mod : x; }
inline int Add( int x, const int &v ) { return ( x += v ) >= mod ? x - mod : x; }

inline int& MulEq( int &x, const int &v ) { return x = 1ll * x * v % mod; }
inline int& SubEq( int &x, const int &v ) { return ( x -= v ) < 0 ? ( x += mod ) : x; }
inline int& AddEq( int &x, const int &v ) { return ( x += v ) >= mod ? ( x -= mod ) : x; } 

inline int S1( int n ) { return Mul( inv2, Mul( n, n + 1 ) ); }
inline int C( int n, int m ) { return n < m ? 0 : Mul( fac[n], Mul( ifac[m], ifac[n - m] ) ); }
inline int CInv( int n, int m ) { return n < m ? 0 : Mul( ifac[n], Mul( fac[m], fac[n - m] ) ); }

inline int Qkpow( int base, int indx ) {
	int ret = 1;
	while( indx ) {
		if( indx & 1 ) MulEq( ret, base );
		MulEq( base, base ), indx >>= 1;
	}
	return ret;
}

inline void Init( const int &n ) {
	fac[0] = 1; rep( i, 1, n ) fac[i] = Mul( fac[i - 1], i );
	ifac[n] = Inv( fac[n] ); per( i, n - 1, 0 ) ifac[i] = Mul( ifac[i + 1], i + 1 );
	rep( i, 1, n ) inv[i] = Mul( ifac[i], fac[i - 1] );
}

int main() {
	Read( N ), Read( M ), Init( N + M );
	int Q = 0, tmp;
	rep( x, 0, N ) {
		P[x] = Mul( Mul( M, inv[N + M] ), Mul( C( N + M, N + M - x ), CInv( N + M - 1, x ) ) );
		 tmp = Mul( Mul( M, inv[N + M] ), Mul( C( N, x ), CInv( N + M - 1, x ) ) );
		AddEq( Q, Mul( tmp, x + 1 ) );
	}
	int ans = 0;
	rep( s, 1, N ) {
		int f = Mul( Inv( Sub( 1, P[N - s] ) ), Q );
		s & 1 ? AddEq( ans, Mul( C( N, s ), f ) ) : SubEq( ans, Mul( C( N, s ), f ) );
	}
	Write( ans ), putchar( '\n' );
	return 0;
}

标签:return,int,CF1392H,Shuffles,const,Mul,Cards,inline,mod
From: https://www.cnblogs.com/crashed/p/17134315.html

相关文章

  • B - Reversible Cards(树与图的基础)
    题目https://atcoder.jp/contests/arc111/tasks/arc111_b题意输入n(≤2e5)和一个n行2列的矩阵,矩阵元素范围[1,4e5]从每行中恰好选一个数,最多能选出多少个不......
  • sklearn 中 ShuffleSplit 函数 的详细使用方法 (机器学习)
    ......
  • Codeforces 1278 F Cards 增强版 题解 (斯特林数,推式子)
    原题链接增强版链接增强版中k=1e7为啥网上题解的式子都那么长啊.jpg首先令\(p=\frac1m\)。求某个数的次幂的题通常都是无脑转下降幂:\(x^k=\sum_{i=0}^kS_2(k,i)x^{\u......
  • ABC247F Cards 题解
    ABC247FCardsSolution目录ABC247FCardsSolution更好的阅读体验戳此进入题面SolutionCodeUPD更好的阅读体验戳此进入题面给定$n$张卡片,每张卡片正反面各有一个......
  • Codeforces Global Round 10 H. ZS Shuffles Cards
    题目链接设f[i]表示还有i个数不在集合内的期望步数,尝试列一下转移式,会发现式子由转移到下一轮的期望步数和之后的DP值组成,考虑DP的转移过程,就会发现答案为转移到下一轮的......
  • 卡片游戏(Throwing cards away I)
    ProblemB:ThrowingcardsawayIGivenisanordereddeckofncardsnumbered1tonwithcard1atthetopandcardnatthebottom.Thefollowingoperationi......
  • CF1539E Game with Cards
    把最终答案看成一段\(0\),一段\(1\)的一个串。如果说我们的答案中有一段\(0\)(\(1\)同理)。那么所有\(0\)的数都满足所有第一个范围,这段\(0\)前面的\(1\)代......
  • CF1392H ZS Shuffles Cards 题解
    linkDescription有\(n\)张数字牌以及\(m\)张鬼牌,有一个不可重集合\(S\),初始为空。不断执行以下操作:抽出一张牌,如果为数字牌,则加入\(S\)并移除。如果为鬼牌,如果......
  • D. Knowledge Cards
    D.KnowledgeCardsPakChanek,arenownedscholar,inventedacardpuzzleusinghisknowledge.Inthepuzzle,youaregivenaboardwith$n$rowsand$m$colum......
  • SAS 用cards/datalines读入原始数据举例
    SAS用cards/datalines读入原始数据:input作用:1)当数据没有这个变量时生成新变量2)读取cards或外部数据。语法:inputinformat.  在input设定的输入格式并不存储在创......