ARC 124 E Pass to Next
- problem
- solution
- code
problem
题目链接
solution
令 ci:c_i:ci: 第 iii 个人传给下一个人球的个数
当 min{ci}≠0\min\{c_i\}\neq 0min{ci}=0 时,将每一个 cic_ici 都减小 111,显然答案序列并不会改变
所以,我们只需要考虑 min{ci}=0\min\{c_i\}=0min{ci}=0 的情况
这样性质的 ccc 序列一共有 ∏i=1n(ai+1)−∏i=1nai\prod_{i=1}^n(a_i+1)-\prod_{i=1}^na_i∏i=1n(ai+1)−∏i=1nai 种,每一种都会导致最后不同的结果序列
至少有一个人是不传球的方案数:总方案数−-−每个人都传球的方案数(将 +1+1+1 看作不传球)
∏i=1nxi=∏i=1n(xi1):\prod_{i=1}^nx_i=\prod_{i=1}^n\binom{x_i}{1}:∏i=1nxi=∏i=1n(1xi): 理解成每个人传完球后,从手里剩下的球中选一个的方案数
所以,我们就可以设计 dpi,0/1dp_{i,0/1}dpi,0/1 转移了
- dpi,0:dp_{i,0}:dpi,0: 第 iii 个人从自己原有的球上选一个,前 i−1i-1i−1 个人的方案数
- dpi,1:dp_{i,1}:dpi,1: 第 iii 个人从第 i−1i-1i−1 个人给的球中选一个,前 iii 个人的方案数
因为是同时一起给下一个人球的,所以每个人手中原本的球可以看成时一种来源,不同来源球直接的分配是相互独立的,前一个人传递过来多少与自己传递多少出去是互不干扰的
-
dpi+1,0←dpi,0⋅ai(ai+1)2dp_{i+1,0}\leftarrow dp_{i,0}·\frac{a_i(a_i+1)}{2}dpi+1,0←dpi,0⋅2ai(ai+1)
由于 dpi,0dp_{i,0}dpi,0 没有算 iii 的贡献,转移时要加上;且这种情况 iii 时从自己手上剩的球中选一个
如果剩下 xxx 个就有 xxx 种选法,而 x∈[1,ai]x\in[1,a_i]x∈[1,ai],所以方案数为 ∑x=1aix\sum_{x=1}^{a_i}x∑x=1aix
-
dpi+1,0←dpi,1⋅(ai+1)dp_{i+1,0}\leftarrow dp_{i,1}·(a_i+1)dpi+1,0←dpi,1⋅(ai+1)
由于 dpi,1dp_{i,1}dpi,1 已经算了 iii 的贡献,转移只需要考虑 i→i+1i\rightarrow i+1i→i+1 的球数,且此情况下先不计算 i+1i+1i+1 在自己手上选球的贡献
传递 0,1,...,ai0,1,...,a_i0,1,...,ai 个一共是 ai+1a_i+1ai+1 种方案
-
dpi+1,1←dpi,0⋅(ai⋅ai(ai+1)2−ai(ai+1)(2ai+1)6)dp_{i+1,1}\leftarrow dp_{i,0}·\Big(a_i·\frac{a_i(a_i+1)}{2}-\frac{a_i(a_i+1)(2a_i+1)}{6}\Big)dpi+1,1←dpi,0⋅(ai⋅2ai(ai+1)−6ai(ai+1)(2ai+1))
由于 i,i+1i,i+1i,i+1 的贡献都没有计算,转移时要一起加上
如果 iii 传递了 xxx 个,那么就还剩下 ai−xa_i-xai−x 个,iii 是从自己手中选,则有 ai−xa_i-xai−x 中选法,i+1i+1i+1 是从 iii 传的球中选一个,则有 xxx 种选法
所以总方案数为 ∑x=1aix(ai−x)=ai⋅∑x=1ai−∑x=1aix2=ai⋅ai(ai+1)2−ai(ai+1)(2ai+1)6\sum_{x=1}^{a_i}x(a_i-x)=a_i·\sum_{x=1}^{a_i}-\sum_{x=1}^{a_i}x^2=a_i·\frac{a_i(a_i+1)}{2}-\frac{a_i(a_i+1)(2a_i+1)}{6}∑x=1aix(ai−x)=ai⋅∑x=1ai−∑x=1aix2=ai⋅2ai(ai+1)−6ai(ai+1)(2ai+1)
-
dpi+1,1←dpi,1⋅ai(ai+1)2dp_{i+1,1}\leftarrow dp_{i,1}·\frac{a_i(a_i+1)}{2}dpi+1,1←dpi,1⋅2ai(ai+1)
由于已经计算了 iii 的贡献,所以只需要考虑 i+1i+1i+1 的贡献
i+1i+1i+1 选的是 iii 传递的球,如果 iii 传了 xxx 个,那么就有 xxx 种选择,方案数为 ∑x=1aix=ai(ai+1)2\sum_{x=1}^{a_i}x=\frac{a_i(a_i+1)}{2}∑x=1aix=2ai(ai+1)
最后因为是个环,所以初始应该钦定 111 的选择
显然这个 dpdpdp 的过程并没有考虑 min{ci}=0\min\{c_i\}=0min{ci}=0 的限制,而是随意转移
所以利用容斥,减去强制至少转移一个球的方案数,就对应着至少有一个人的 ci=0c_i=0ci=0 的方案数
具体而言:
iii 从自己手上剩的球选择,剩的球就被限制为了 1,2,...,ai−11,2,...,a_{i-1}1,2,...,ai−1
转移变为 dpi+1,0←dpi,0⋅ai(ai−1)2dp_{i+1,0}\leftarrow dp_{i,0}·\frac{a_i(a_i-1)}{2}dpi+1,0←dpi,0⋅2ai(ai−1)
iii 传递给 i+1i+1i+1 至少都是一个球 1,2,...,ai1,2,...,a_i1,2,...,ai
转移变为 dpi+1,0←dpi,1⋅aidp_{i+1,0}\leftarrow dp_{i,1}·a_idpi+1,0←dpi,1⋅ai
而
case3
case4
的转移,因为为了使 (x1)\binom{x}{1}(1x) 有意义,所以 xxx 自带条件就是 ≥1\ge 1≥1,转移不变
code
#include <cstdio>
#include <cstring>
#define int long long
#define mod 998244353
#define maxn 300005
const int inv2 = ( mod + 1 ) / 2;
const int inv6 = ( mod + 1 ) / 6;
int n;
int a[maxn];
int dp[maxn][2];int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}int solve( int o, int k ) {memset( dp, 0, sizeof( dp ) );dp[1][o] = 1;for( int i = 1, x, g, f;i <= n;i ++ ) {x = a[i] - k;g = x * ( x + 1 ) % mod * inv2 % mod;dp[i + 1][0] = ( dp[i][0] * g + dp[i][1] * ( x + 1 ) ) % mod;x = a[i];g = x * ( x + 1 ) % mod * inv2 % mod;f = x * ( x + 1 ) % mod * ( x << 1 | 1 ) % mod * inv6 % mod;dp[i + 1][1] = ( ( a[i] * g - f ) % mod * dp[i][0] + dp[i][1] * g ) % mod;}return dp[n + 1][o];
}signed main() {scanf( "%lld", &n );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &a[i] );printf( "%lld\n", ( ( solve( 1, 0 ) + solve( 0, 0 ) - solve( 0, 1 ) - solve( 1, 1 ) ) % mod + mod ) % mod );return 0;
}