bzoj2655 calc 拉格朗日插值

2021-08-17 17:53:35 字數 1829 閱讀 6378

description:

乙個序列a1

,...

,an a1,

...,

an

是合法的,當且僅當:

長度為給定的

n n

。 a1

,...

,an' role="presentation" style="position: relative;">a1,

...,

ana1

,...

,an都是

[1,a

] [1,

a]

中的整數。 a1

,...

,an a1,

...,

an

互不相等。

乙個序列的值定義為它裡面所有數的乘積,即a1

a2..

.an a1a

2...

an

。 求所有不同合法序列的值的和。

兩個序列不同當且僅當他們任意一位不一樣。

輸出答案對乙個數mo

d mod

取餘的結果。

solution:

考慮乙個暴力的dp

,dp[

i][j

] dp,

dp[i

][j]

表示前i i

個數選j' role="presentation" style="position: relative;">j

j個數。

那麼轉移即為dp

[i][

j]=d

p[i−

1][j

]+dp

[i−1

][j−

1]∗i

∗jd p[

i][j

]=dp

[i−1

][j]

+dp[

i−1]

[j−1

]∗i∗

j表示選或不選,並且列舉插入的位置。

由於這個dp

d

p式是乙個2∗

n 2∗n

的多項式,所以我們插值求第

a a

項即可。

注意插值如果從

1' role="presentation" style="position: relative;">1

1開始要插到2∗

n+1 2∗n

+1

次。

#include 

using namespace std;

typedef long long ll;

const int maxn = 1005;

int n, a, p;

ll pre[maxn], suf[maxn], inv[maxn], dp[maxn][maxn];

ll calc(ll *f, ll u, int n)

for(int i = n + 1; i; --i)

ll ret = 0, tmp;

for(int i = 1; i <= n + 1; ++i)

ret = (ret + tmp) % p;

}return ret;

}int main()

for(int i = 2; i < maxn; ++i)

dp[0][0] = 1;

for(int j = 1; j <= 2 * n + 1; ++j) }}

if(a <= 2 * n) else

return 0;

}

bzoj 2655 calc 拉格朗日插值

題目 先設 f i j 表示長度為 i 的序列,範圍是 1 j 的答案 則 f i j f i 1 j 1 i j f i j 1 分別是選不選 j,選 j 的話放在哪個位置 看不出次數.據說這是個最高次數為 2i 的多項式,感性理解.知道了次數,就可以用拉格朗日插值算了,dp得到比較小的 2 n ...

BZOJ2655 拉格朗日插值 calc

bzoj2655 考慮dp的話是f i j i f i 1 j 1 f i 1 j f i j i f i 1 j 1 f i 1 j f i j i f i 1 j 1 f i 1 j 分別表示選當前這個數和不選 然而i ii很大,有1e9 發現每次轉移乘上的是乙個i ii,且j 1 j 1j 1...

拉格朗日插值與拉格朗日反演

模板 拉格朗日插值 拉格朗日插值法 f x sum limits 我們先把右邊那部分提出來看 ell x prod x x cdots x x cdots x 舉個例子吧 有二次函式上的三點 f 4 10,f 5 5.25,f 6 1 求 f 18 求出三個基本式 ell x ell x ell x...