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...