【NOI2019】斗主地【期望】【组合数学】【下降幂】【插值】

题意:

n n n张牌,从上往下的第 i i i张牌权值是 f ( i ) = i t y p e f(i)=i^{type} f(i)=itype

进行 m m m次洗牌操作,每次操作给定 a i a_i ai,将从上往下的前 a i a_i ai张牌分成一堆,后面 b i b_i bi张牌分成第二堆。如果两堆的牌数分别为 X , Y X,Y X,Y,则有 X X + Y \frac{X}{X+Y} X+YX的概率将第一堆的最下面一张牌放在第三堆的最上面,否则将第二堆的最下面放到第三堆的最上面,直到两边都没有牌,第三堆为最终结果。

最后 q q q次询问从上往下第 c i c_i ci张牌的期望权值 模 998244353 998244353 998244353

n ≤ 1 0 7 , m , q ≤ 5 × 1 0 5 , t y p e ∈ { 1 , 2 } n\leq 10^7,m,q\leq5\times 10^5,type\in\{1,2\} n107,m,q5×105,type{1,2}

题本身不错,但结论太好猜,而且要证明必须要先猜出来,出在NOI还是比较失败的

结论1 k k k次洗牌可以看成把第 k − 1 k-1 k1次洗牌后每张牌的期望看成权值洗牌

根据期望的线性性应该很容易理解。

式子证明:

设第 k − 1 k-1 k1次洗牌后第 i i i张牌是原来的第 j j j张牌的概率是 P ( i , j ) P(i,j) P(i,j)
k k k次洗牌后第 i i i张牌对应第 k − 1 k-1 k1次的第 j j j张牌的概率为 P ′ ( i , j ) P'(i,j) P(i,j)
那么第 k k k次后对应原来的编号是
P ′ ′ ( i , j ) = ∑ k = 1 n P ′ ( i , k ) P ( k , j ) P''(i,j)=\sum_{k=1}^nP'(i,k)P(k,j) P(i,j)=k=1nP(i,k)P(k,j)
k − 1 k-1 k1次后第 i i i张牌的期望是
E ( i ) = ∑ j = 1 n P ( i , j ) F ( j ) E(i)=\sum_{j=1}^nP(i,j)F(j) E(i)=j=1nP(i,j)F(j)
把它看成权值洗第 k k k
E ′ ( i ) = ∑ j = 1 n P ′ ( i , j ) E ( j ) = ∑ j = 1 n P ′ ( i , j ∑ k = 1 n P ( j , k ) f ( k ) = ∑ j = 1 n ∑ k = 1 n P ′ ( i , k ) P ( k , j ) f ( j ) = ∑ j = 1 n P ′ ′ ( i , j ) f ( j ) E'(i)=\sum_{j=1}^nP'(i,j)E(j)\\ =\sum_{j=1}^nP'(i,j\sum_{k=1}^nP(j,k)f(k)\\=\sum_{j=1}^n\sum_{k=1}^nP'(i,k) P(k,j)f(j)\\=\sum_{j=1}^nP''(i,j)f(j) E(i)=j=1nP(i,j)E(j)=j=1nP(i,jk=1nP(j,k)f(k)=j=1nk=1nP(i,k)P(k,j)f(j)=j=1nP(i,j)f(j)

结论2 题目中洗牌的方式相当于 ( n a i ) \binom n {a_i} (ain)种方案等概率随机选择一种。

即:这 ( n a i ) \binom n {a_i} (ain)种方案出现的概率都相等

考虑一个长度为 n n n 、有 a i a_i ai 0 0 0 01 01 01序列 s s s 0 0 0表示取第一堆, 1 1 1表示取第二堆,它和最终洗牌后的牌堆情况一一对应,每个位置选择的概率只和它后缀中 0 0 0 1 1 1的数量有关。

考虑交换两个相邻的 0 0 0 1 1 1,设它们的下标是 i i i i + 1 i+1 i+1,不妨设 s i = 0 , s i + 1 = 1 s_i=0,s_{i+1}=1 si=0,si+1=1

1 ∼ i − 1 1\sim i-1 1i1 i + 2 ∼ n i+2\sim n i+2n的位置后缀 01 01 01数量都没有变化,贡献的概率都是一样的。

i + 2 ∼ n i+2\sim n i+2n中有 x x x 0 0 0 y y y 1 1 1

交换前这两位的概率是 x + 1 x + y ⋅ y + 1 x + y − 1 \frac{x+1}{x+y}\cdot\frac{y+1}{x+y-1} x+yx+1x+y1y+1

交换后的概率是 y + 1 x + y ⋅ x + 1 x + y − 1 \frac{y+1}{x+y}\cdot\frac{x+1}{x+y-1} x+yy+1x+y1x+1

所以交换后的概率都是相等的

进而得到所有情况的概率都相等

Q: 按这种思路,为什么按 1 2 \frac{1}{2} 21的概率选一堆就不是均匀随机了呢?

A: 如果可以完全保证 1 2 \frac 12 21的概率,那么也是均匀随机的。但问题出在一堆选完之后,就只能选剩下的一堆,概率实际上不是 1 2 \frac 12 21,导致最终结果不均匀。而本题中选完之后概率就是 0 0 0,并没有特殊情况。

结论3 无论洗多少次牌,牌堆中第 i i i张牌的期望权值都是关于 i i i的不超过 t y p e type type次的多项式。

采用归纳法,假设第 m − 1 m-1 m1次后是个 t y p e type type次的多项式,需要证明再洗一次仍然是 t y p e type type次多项式。

设在 m − 1 m-1 m1次后第 i i i张牌的期望是 E ( i ) E(i) E(i) m m m次后是 E ′ ( i ) E'(i) E(i)。我们尝试用 E E E来表示出 E ′ ( i ) E'(i) E(i),即计算出概率 P ′ ( i , j ) P'(i,j) P(i,j)

因为是等概率随机的,计算概率就等价于计算方案数。记 a m = A a_m=A am=A,以下的推导中均省略分母中的 ( n A ) \binom nA (An)

不妨设 j ≤ a m j\leq a_m jam,即只考虑分到第一堆的牌的贡献,分到第二堆是同理的

我们要让 j j j落到 i i i的位置上,那么在 i i i前面选择的第一堆的牌需要恰好 j − 1 j-1 j1张, i i i后面通过组合数算出贡献的方案

P ′ ( i , j ) = ( i − 1 j − 1 ) ( n − i A − j ) P'(i,j)=\binom{i-1}{j-1}\binom{n-i}{A-j} P(i,j)=(j1i1)(Ajni)

那么可以得到

E ′ ( i ) = ∑ j = 1 A ( i − 1 j − 1 ) ( n − i A − j ) E ( j ) E'(i)=\sum_{j=1}^A\binom{i-1}{j-1}\binom{n-i}{A-j}E(j) E(i)=j=1A(j1i1)(Ajni)E(j)

你把两个组合数拆一下,发现完全没有像常数的意思,不说 t y p e type type次了,都有点怀疑是不是多项式。

但还有个重要的性质没用: E ( j ) E(j) E(j)本身也是 t y p e type type次的多项式

当然前面一堆组合数,带几个单项式进去显然没有任何作用。

但看到多项式又有组合数,你想到了什么?阶乘幂啊!

E ( j ) E(j) E(j)转成下降幂多项式,然后考虑每个下降幂单项式 j k ‾ ( k ≤ t y p e ) j^{\underline k}(k\leq type) jk(ktype)的贡献

∑ j = 1 A ( i − 1 j − 1 ) ( n − i A − j ) j k ‾ \sum_{j=1}^A\binom{i-1}{j-1}\binom{n-i}{A-j}j^{\underline k} j=1A(j1i1)(Ajni)jk

……等等,前面的分母都有 ( j − 1 ) ! (j-1)! (j1)!了,我们干脆拆成 ( j − 1 ) k ‾ (j-1)^{\underline k} (j1)k好了

∑ j = 1 A ( i − 1 j − 1 ) ( n − i A − j ) ( j − 1 ) k ‾ \sum_{j=1}^A\binom{i-1}{j-1}\binom{n-i}{A-j}(j-1)^{\underline k} j=1A(j1i1)(Ajni)(j1)k

看着难受,除一个 k ! k! k!转成组合数

∑ j = 1 A ( i − 1 j − 1 ) ( n − i A − j ) ( j − 1 k ) \sum_{j=1}^A\binom{i-1}{j-1}\binom{n-i}{A-j}\binom{j-1}{k} j=1A(j1i1)(Ajni)(kj1)

∑ j = 1 A ( i − 1 j − 1 ) ( n − i A − j ) ( j − 1 k ) \sum_{j=1}^A\binom{i-1}{j-1}\binom{n-i}{A-j}\binom{j-1}{k} j=1A(j1i1)(Ajni)(kj1)

= ∑ j = 1 A ( i − 1 j − 1 ) ( j − 1 k ) ( n − i A − j ) =\sum_{j=1}^A\binom{i-1}{j-1}\binom{j-1}{k}\binom{n-i}{A-j} =j=1A(j1i1)(kj1)(Ajni)

= ∑ j = 1 A ( i − 1 k ) ( i − k − 1 i − j ) ( n − i A − j ) =\sum_{j=1}^A\binom{i-1}{k}\binom{i-k-1}{i-j}\binom{n-i}{A-j} =j=1A(ki1)(ijik1)(Ajni)

= ( i − 1 k ) ∑ j = 1 A ( i − k − 1 i − j ) ( n − i A − j ) =\binom{i-1}{k}\sum_{j=1}^A\binom{i-k-1}{i-j}\binom{n-i}{A-j} =(ki1)j=1A(ijik1)(Ajni)

= ( i − 1 k ) ∑ j = 1 A ( i − k − 1 j − k − 1 ) ( n − i A − j ) =\binom{i-1}{k}\sum_{j=1}^A\binom{i-k-1}{j-k-1}\binom{n-i}{A-j} =(ki1)j=1A(jk1ik1)(Ajni)

引理
∑ i ( n i ) ( m k − i ) = ( n + m k ) \sum_i\binom ni\binom m{k-i}=\binom{n+m}k i(in)(kim)=(kn+m)
理性愉悦
构造
( x + 1 ) n ( x + 1 ) m = ( x + 1 ) n + m (x+1)^n(x+1)^m=(x+1)^{n+m} (x+1)n(x+1)m=(x+1)n+m
比较 x k x^k xk项系数得证
感性愉悦
n + m n+m n+m件物品选择 k k k件,等价于分成 n n n m m m两堆,在前一堆选任意 i i i件,在另一堆选剩下的 k − i k-i ki件。

= ( i − 1 k ) ( n − k − 1 A − k − 1 ) =\binom{i-1}{k}\binom{n-k-1}{A-k-1} =(ki1)(Ak1nk1)

左边就是关于 i i i k k k次下降幂多项式,也就是 k k k次多项式,右边是个无关的常数。因为 k ≤ t y p e k\leq type ktype,所以得到的仍然是 t y p e type type次的多项式。


因为 t y p e ≤ 2 type\leq 2 type2,所以维护 3 3 3个点值就可以 O ( 1 ) O(1) O(1)算出任意位置的答案。这里由于懒得写阶乘,维护的是第 0 0 0项、第一个公差、二阶公差。

在洗牌的时候先插值算出两堆的前 3 3 3个,然后暴力枚举求出洗牌后前 3 3 3个的期望。

另外注意题目中从上到下和从下到上的表述。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
using namespace std;
const int MOD=998244353;
typedef long long ll;
inline int qpow(int a,int p)
{
	int ans=1;
	while (p)
	{
		if (p&1) ans=(ll)ans*a%MOD;
		a=(ll)a*a%MOD;p>>=1;
	}
	return ans;
}
int A,B,C;
inline int calc(int x){return (A+(ll)B*x+(ll)x*(x-1)/2%MOD*C)%MOD;}
int main()
{
	int n,m,type;
	scanf("%d%d%d",&n,&m,&type);
	if (type==1) A=n+1,B=MOD-1;
	else A=(n+1ll)*(n+1)%MOD,B=(MOD-2*n-1),C=2;
	int inv[3]={qpow(n,MOD-2),qpow(n-1,MOD-2),qpow(n-2,MOD-2)};
	while (m--)
	{
		int k;
		scanf("%d",&k);
		k=n-k;
		int a[3]={calc(1),calc(2),calc(3)},b[3]={calc(k+1),calc(k+2),calc(k+3)},c[3]={};
		for (int S=0;S<8;S++)
		{
			int cnt[2]={},v=1,x=k,y=n-k;
			for (int i=0;i<3;i++) 
			{
				if ((S>>i)&1) ++cnt[1],v=(ll)v*y%MOD*inv[i]%MOD,--y;
				else ++cnt[0],v=(ll)v*x%MOD*inv[i]%MOD,--x;
			}
			if (cnt[0]>k||cnt[1]>n-k) continue;
			cnt[0]=cnt[1]=0;
			for (int i=0;i<3;i++)
			{
				if ((S>>i)&1) c[i]=(c[i]+(ll)v*b[cnt[1]])%MOD,++cnt[1];
				else c[i]=(c[i]+(ll)v*a[cnt[0]])%MOD,++cnt[0];
			}
		}
		C=((c[2]-2*c[1]+c[0])%MOD+MOD)%MOD;
		B=((c[1]-c[0]-C)%MOD+MOD)%MOD;
		A=(c[0]-B+MOD)%MOD;
	}
	int q;
	scanf("%d",&q);
	while (q--)
	{
		int x;
		scanf("%d",&x);
		printf("%d\n",calc(n-x+1));
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值