首页 > 其他分享 >Atcoder ABC 333 题解(A - F)

Atcoder ABC 333 题解(A - F)

时间:2023-12-19 12:44:27浏览次数:20  
标签:Atcoder ABC frac int 题解 ll 3005 高斯消 mod

ABC

不讲

D

待更

E

待更

F

设 $ f(i, j) $ 为有 $ i $ 个人时,第 $ j $ 个人活到最后的概率,显然:

\[ f(i, j) = \begin{cases} 1, & i = 1, j = 1 \\ \frac{1}{2}f(i, i), & i \neq 1, j = 1 \\ \frac{1}{2}f(i, j - 1) + \frac{1}{2}f(i - 1, j - 1), & i \neq 1, 2 \le j \le i \end{cases} \]

但是这个转移方程有后效性。

观察转移方程,可以发现 $ i $ 是没有后效性的,于是可以用 DP 套高斯消元的方法解。

我们将 $ f(i, 1), f(i, 2), \cdots, f(i, i) $ 视作未知数,将 $ f(i - 1, 1), f(i - 1, 2), \cdots, f(i - 1, i - 1) $ 视作已知数,可以得到 $ i $ 元一次方程:

\[ \begin{cases} -f(i, 1) + \frac{1}{2}f(i, i) = 0 \\ -f(i, 2) + \frac{1}{2}f(i, 1) = -\frac{1}{2}f(i - 1, 1) \\ -f(i, 3) + \frac{1}{2}f(i, 2) = -\frac{1}{2}f(i - 1, 2) \\ \cdots \\ -f(i, i) + \frac{1}{2}f(i, i - 1) = -\frac{1}{2}f(i - 1, i - 1) \end{cases} \]

于是就可以愉快的高斯消元了。但是如果用一般的高斯消元,高斯消元的时间复杂度是 $ O(n ^ 3) $,总的时间复杂度是 $ O(n ^ 4) $。

把增广矩阵拎出来康康:(以 $ i = 5 $ 为例)

\[ \left[ \begin{array}{ccccc|c} -1 & 0 & 0 & 0 & \frac{1}{2} & 0 \\ \frac{1}{2} & -1 & 0 & 0 & 0 & -\frac{1}{2}f(4, 1) \\ 0 & \frac{1}{2} & -1 & 0 & 0 & -\frac{1}{2}f(4, 2) \\ 0 & 0 & \frac{1}{2} & -1 & 0 & -\frac{1}{2}f(4, 3) \\ 0 & 0 & 0 & \frac{1}{2} & -1 & -\frac{1}{2}f(4, 4) \end{array} \right] \]

观察得知每行只有 $ 2 $ 个位置要消元,所以可以在 $ O(n) $ 的时间内高斯消元。

具体做法:用第 $ k $ 行减第 $ k + 1 $ 行,消完元后矩阵将只有对角线和最后一列有数,把第 $ i $ 列的数减掉就可以了。

注:$ -1 \equiv 998244352 \pmod{998244353} $ ,$ \frac{1}{2} \equiv 499122177 \pmod{998244353} $ ,$ -\frac{1}{2} \equiv 499122176 \pmod{998244353} $ 。


#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define mod 998244353

ll f[3005][3005];
ll a[3005][3005], b[3005];

ll qpow(ll a, ll x, ll m) {
	ll ans = 1;
	while (x) {
		if (x & 1) {
			ans = ans * a % m;
		}
		x >>= 1;
		a = a * a % m;
	}
	return ans;
}

void multiply_by_and_subtract(int x, ll k, int y, int n) {
	a[y][x] = (a[x][x] * k % mod + mod - a[y][x]) % mod;
	a[y][y] = (a[x][y] * k % mod + mod - a[y][y]) % mod;
	if (y != n) {
		a[y][n] = (a[x][n] * k % mod + mod - a[y][n]) % mod;
	}
	b[y] = (b[x] * k % mod + mod - b[y]) % mod;
}

#define decrease multiply_by_and_subtract

void gauss(int n) {
	for (int i = 1; i <= n; i++) {
		a[i][i] = 998244352, a[i][(i - 1) ? (i - 1) : (n)] = 499122177;
		b[i] = f[n - 1][i - 1] * 499122176 % mod;
	}
	for (int i = 1; i < n; i++) {
		decrease(i, a[i + 1][i] * qpow(a[i][i], mod - 2, mod) % mod, i + 1, n);
	}
	b[n] = b[n] * qpow(a[n][n], mod - 2, mod) % mod;
	a[n][n] = 1;
	for (int i = 1; i < n; i++) {
		b[i] = (b[i] - a[i][n] * b[n] % mod + mod) % mod;
		b[i] = b[i] * qpow(a[i][i], mod - 2, mod) % mod;
		a[i][n] = 0;
	}
}

int main() {
	int n;
	scanf("%d", &n);
	f[1][1] = 1;
	for (int i = 2; i <= n; i++) {
		gauss(i);
		for (int j = 1; j <= n; j++) {
			f[i][j] = b[j];
		}
	}
	for (int i = 1; i <= n; i++) {
		printf("%lld ", f[n][i]);
	}
}

标签:Atcoder,ABC,frac,int,题解,ll,3005,高斯消,mod
From: https://www.cnblogs.com/AProblemSolver/p/17913470.html

相关文章

  • Queries for the Array 题解
    前言这场CF是我赛后打的,vp赛时没做出来,后来发现是有个地方理解错了,有一些细节没有考虑到。现在换了一种思路来写,感觉更清晰了。做法首先需要动态维护三个变量,\(cnt\)和\(finishsort\)和\(unfinishsort\)。这三个变量分别表示当前数字的个数,已经排好序的最后一个位置,和没......
  • poker 题解
    原题链接:poker赛时只有\(40\)分,改完之后感觉是一道好题,于是就来写篇题解。题意有\(k\)张扑克牌,\(n\)种数字,每张牌都有两面,每一面分别写了一个数字,你可以选择打出这张牌的任意一面,但是不能两面同时打,也可以选择不打这张牌。有\(q\)个询问,每个询问给定\(l\)和\(r\),判断......
  • P3694 邦邦的大合唱站队 题解
    原题链接:P3694思路状态设计因为这道题\(m\)的范围非常小,所以可以用\(m\)来作为状态。设\(dp_{i}\)表示\(m\)支队伍的状态为\(i\)时最少让多少偶像出列。预处理在转移之前,我们先要预处理出序列的前缀和\(sum_{i,j}\)表示第\(i\)个数之前有多少个值为\(j\)......
  • [ABC325G] offence
    题意给定一个长度为\(n\)字符串以及一个数\(f\),你可以执行以下操作任意次,求最终字符串长度的最小值。在字符串中选择一个连续的of,删掉它以及它后面的\(i\)个字符,\(0\lei\lef\)。数据范围:\(n\le300\)。思路看到数据范围以及字符串中间的删除可以想到区间dp。......
  • [AGC054C] Roughly Sorted 题解
    题意定义一种操作为交换\(a_{i}\)和\(a_{i-1}\)。对于一个长度为\(n\)的排列,你需要操作若干次,使这个序列变合法,一个序列合法指:满足对于每一个\(1\lei\len\),都满足包含\(a_i\)的逆序对的个数不超过\(k\),并且要求最小化操作次数。现在给定一个操作后的序列,询问原序列可......
  • P2391 白雪皑皑 题解
    原题链接:P2391。并查集好题。首先我们知道,并查集在一个无向图中可以维护两点之间的连通性,判断条件为:\(find(u)==find(v)\)。而对于这道题来说,我们可以用并查集来维护一个序列区间的重叠性或者说区间的连通性。因为题目上说了后面的操作会覆盖前面的操作,所以我们可以考虑倒序进行......
  • [ABC239Ex] Dice Product 2 题解
    原题链接:ABC239Ex。题意不多赘述。看到求期望值,我们想到可以用期望DP。设\(dp_{i}\)表示最终结果大于等于\(i\)时的操作次数的期望值。那么我们可以得到一个基本的状态转移方程:\(dp_{i}=\frac{1}{n}\times\sum_{j=1}^{n}dp_{\left\lceil\frac{i}{j}\right\rceil}+......
  • Prefix Purchase 题解
    题意给定一个长度为\(n\)的序列\(ans\),初始值全部为\(0\)。你一共有\(k\)个硬币,你可以选择花\(a_{i}\)个硬币来使\(ans_{1}\)到\(ans_{i}\)中的所有数加一。求最终能得到的\(ans\)序列中字典序最大的一个。思路首先我们可以发现一个很显然的性质:如果满足\(a_{i}......
  • Sum of XOR Functions 题解
    题意给定一个数\(n\)和一个包含\(n\)个数的序列\(a\),求出以下式子模\(998244353\)的值:\(\sum_{i=1}^{n}\sum_{j=i}^{n}f(i,j)\times(j-i+1)\)。其中\(f(i,j)\)的值为\(a_{i}\oplusa_{i+1}\oplusa_{i+2}\oplus...\oplusa_{j}\)。思路首先我们可以考虑这道题的......
  • Candy Party (Hard Version) 题解
    原题链接:CF1868B2,简单版:CF1868B1。题意有\(n\)个人,第\(i\)个人手上最初有\(a_{i}\)颗糖。现在每个人可以把自己手中的糖选一些给不多于一个人,同时每个人也只能接受不多于一个人的糖,选出的糖的数量必须是二的次幂。问能否能让每个人最终手上的糖的数量相等。思路首先,这......