1. 程式人生 > >AtCoder [Dwango Programming Contest V] E 動態規劃 多項式

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;
}