AtCoder [Dwango Programming Contest V] E 動態規劃 多項式
原文連結 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]\times (i-1) + dp[i-1][j-1] \times 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})$ 。
引理
設 $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; }