Solution Of P11281「GFOI Round 2」Aob & Blice
Preface
神秘的好题。
虽然棕名但求过,之前公开赛大小号交同一份代码棕了。本人并不存在抄袭。
Solution
我们直接考虑在游戏轮数趋于无穷时的情况。
此时,我们注意到所有的
我们看一下 Blice 基于 Aob 能产生的三种数对,分别是
然后我们会注意到,
接下来我们考虑如何统计方案。
首先为了满足条件,有一些
然后我们考虑递推求解,设方案数为
下面给出对于
我们发现命题实际上等价于建立一个有向图
那么
-
先证必要性:
你会发现对于所有
1\le x < y\le n,p_x > p_y ,有(x,y) = (p_y, p_x),(p_x, p_y) = (y,x),(p_{p_y}, p_{p_x}) = (y, x) ,证好了。 -
再证充分性:
考虑反证,若不满足条件,此时图中必定存在节点数大于三的一个环,不妨设这个环的节点编号集为
M=\{u_1, u_2,\dots,u_k\} ,我们记M 所能产生在S_A 的\{(x,y),(p_x,p_y)\} = T_A ,能在S_B 中产生的\{(y,x),(p_y,p_x),(p_{p_y}, p_{p_x})\} = T_B ,那么我们由定义显然有x\in M, y\in M,p_x\in M, p_y\in M ,因此T_A 和T_B 是封闭的。所以若S_A=S_B 那么T_A = T_B 。我们不妨设
u_1<u_2<\dots<u_k ,因此(u_{k-1},u_{k})\in T_A ,但是由穷举可得,(u_{k-1},u_{k}) 一定不属于T_B (由于p_{u_i} = u_{i + 1}(1\le i < k),p_{u_k} = u_1 因此你只要穷举(u_{k-2},u_{k-1}),(u_{k}, u_{k-1}),(u_{k}, u_1) 对T_B 能贡献的数对,这显然是极其有限的,因此可以直接穷举),于是矛盾,证毕。
Code
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
constexpr int P = 998244353, N = 1e6 + 3;
int n, p[N], x = 1;
i64 res[N] = {0, 1, 2}, ans;
int main() {
cin.tie(nullptr), cout.tie(nullptr)
-> sync_with_stdio(false); cin >> n;
for (int i = 1; i <= n; i ++) cin >> p[i];
for (int i = 1; i <= n; i ++) if (p[p[i]] != i) x = 0;
if (x) return cout << 1, 0;
for (int i = 1; i <= n; i ++) if (p[i]) {
if (p[p[i]] == 0) p[p[i]] = i;
else if (p[p[i]] != i) return cout << 0, 0;
}
for (int i = 1; i <= n; i ++) if (!p[i]) ans ++;
for (int i = 3; i <= n; i ++)
res[i] = (res[i - 1] + res[i - 2] * (i - 1) % P) % P;
return cout << res[ans], 0;
}