原文链接 https://www.cnblogs.com/zhouzhendong/p/AtCoder-Dwango-Programming-Contest-V-E.html
题意
有 $n$ 个数,第 $i$ 个数为 $a_i$ ,对于任意一个 $1,2,cdots ,n$ 的排列 $P$ ,如果将所有边 $(i,P_i)$ 相连,那么必然得到一些环。定义函数 $f(P)=prod_{r 是 P 中的一个环} r 中最小的 a_i 值$ 。定义 $S(i)=sum_{P代表i 个环} f(P)$ ,求 $gcd(S(1),S(2),cdots ,S(n))$ 。
题解
好久没发博客了。我的退役生活被 10 门丰富多彩的学科暴虐。
首先将 $a_i$ 升序排列。
设 $dp[i][j]$ 为前 $i$ 个数分成 $j$ 个环对答案的贡献。
那么
$$dp[i][j] = dp[i-1][j] imes (i-1) + dp[i-1][j-1] imes a_i$$
其中初始值为 $dp[0][0]=1$ 。
则题目要求的就是 $gcd(dp[n][1],dp[n][2],cdots ,dp[n][n])$ 。
设 $g_k(x) = sum_{i=0}^{n} dp[k][i] x^i$,则有 $g_{k+1}(x) = (k+a_{k+1}x)g_k(x)$ 。
即 $g_n(x) = prod_{i=0}^{n-1} (i+a_{i+1}x)$ 。
引理
设 $P,Q$ 为多项式,定义函数 $G(P)=gcd(P_0,P_1,cdots)$ ,其中 $P_i$ 为多项式 $P$ 的 $i$ 次项。那么,必然有 $G(PQ) = G(P)G(Q)$ 。
证明上面的引理,只需要转化成一个显然的引理即可:
若 $G(P) = G(Q) = 1$,则 $G(PQ) = 1$ 。
引理完
于是最终答案就是 $prod_{i=0}^{n-1} gcd(i,a_{i+1})$ 。
代码
#include <bits/stdc++.h> using namespace std; const int N=100005,mod=998244353; int n,a[N]; int gcd(int a,int b){ return b?gcd(b,a%b):a; } int main(){ cin >> n; for (int i=0;i<n;i++) cin >> a[i]; sort(a,a+n); int ans=1; for (int i=0;i<n;i++) ans=1LL*ans*gcd(a[i],i)%mod; cout << ans; return 0; }