國家集訓隊 calc

2022-05-09 10:57:16 字數 1567 閱讀 6162

嘟嘟嘟

這道題dp雖然不難,但是我還是沒推出來,感覺最近腦子不太好用啊。

於是就跑去問神仙gjx(全國前三!)了。(外出集訓真是好)

神仙不愧是神仙,一會兒就想出來了,而且方法還比網上的題解好懂。

dp[i][j]表示用值域為[1, i]的數,湊出的所有合法序列的值的和。

然後規定序列必須是嚴格遞增的,這樣答案再乘以乙個\(n!\)就行了。

轉移的時候,我們考慮\(i\)這個數用不用上,於是有:\(dp[i][j] = dp[i - 1][j] +i * dp[i - 1][j - 1]\)。現在感覺這個挺好理解的,如果用上\(i\)了,\(i\)就必須放在最後面,並且答案要乘以\(i\)。

但這個複雜度\(o(na)\)的,\(a\)太大不好辦。

然後gjx大佬告訴我,這個dp式是乙個關於\(j\)的\(2n\)次多項式,然後給我證了一下,但還是不太懂:

首先知道\(dp[i][1] = \frac\),猜想這可能是乙個\(2n\)次的。

然後把轉移方程中的\(dp[i - 1][j]\)不斷展開,得到了\(dp[i][j] = \sum _ ^ dp[k][j] *(k + 1)\)。於是發現,這是乙個關於\(j\)的\(2n\)次多項式。

(感覺自己還是不太理解)

(這篇題解的證明好像也不錯, 應該是數學歸納法,我得學一下)

知道這是個多項式,就可以拉格朗日差值了。

注意dp的邊界取值,我這裡debug了好久。

#include#include#include#include#include#include#include#include#include#includeusing namespace std;

#define enter puts("")

#define space putchar(' ')

#define mem(a, x) memset(a, x, sizeof(a))

#define in inline

typedef long long ll;

typedef double db;

const int inf = 0x3f3f3f3f;

const db eps = 1e-8;

const int maxn = 505;

inline ll read()

inline void write(ll x)

int a, n, mod;

ll fac[maxn << 1], dp[maxn << 1][maxn];

in ll quickpow(ll a, ll b)

ll inv[maxn << 1], pre[maxn << 1], suf[maxn << 1];

in ll calc(int n)

return ret;

}int main()

if(a <= (n << 1)) write(dp[a][n] * fac[n] % mod), enter;

else write(calc(n << 1) * fac[n] % mod), enter;

return 0;

}

國家集訓隊 旅遊

題目背景 ray 樂忠於旅遊,這次他來到了 t 城。t 城是乙個水上城市,一共有 nn 個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,t 城的任意兩個景點之間有且只有一條路徑。換句話說,t 城中只有 n 1n 1 座橋。ray 發現,有些橋上可以看到美麗的景色,讓人心...

國家集訓隊 Tree I

題目 給你乙個無向帶權連通圖,每條邊是黑色或白色。讓你求一棵最小權的恰好有nee dneed need 條白色邊的生成樹。題目保證有解。思路 凸優化裸題,要注意的就是,優先選白色 優先選黑色也行 主要是同一斜率可能會切到很多點,那麼就要有乙個標準,要麼選最小點,要麼選最大。另外求出來的點不一定是ne...

國家集訓隊 旅遊

ray 樂忠於旅遊,這次他來到了 t 城。t 城是乙個水上城市,一共有 n 個景點,有些景點之間會用一座橋連線。為了方便遊客到達每個景點但又為了節約成本,t 城的任意兩個景點之間有且只有一條路徑。換句話說,t 城中只有 n 1 座橋。ray 發現,有些橋上可以看到美麗的景色,讓人心情愉悅,但有些橋狹...