説明:
\(1 <= N、K <= 1E5、MOD〜1E9 + 7 \)
ソリューション:
DPは、最も古典的な配置は、それぞれが最初に挿入されたと見なさ\(Iは\)多数、それは逆の数が増加することができる\(I - 0 1 \) 。
機能を生成すると、取得するのは簡単です:
\(ANS = \ prod_ {i = 0} ^ {N-1}(\ sum_ {J = 0} ^ IX ^ J)[X ^ K] \)
\(= \ prod_ {i = 1} ^ {n}は{1-x ^ I \オーバー1-x} [X ^ K] \)
分母は、生成関数の古典であります:
\({1 \ 1-Xオーバー} ^ N =(\ sum_ {I> = 0} X ^ I)^ N = \ sum_ {iが> = 0} C_ {I + N-1} ^ {N-1 } \)
問題はその後の要求のようになります。
\(\ prod_ {i = 1 } ^ {n}は{1-x ^ I} \) 最初のk個のエントリ。
DPは、整数除算を使用することを検討別に対応する数に分割され、K <= N及び係数の数である\((--1)} ^ {カウント数\) 。
DP来ることは困難ではありません。
セット\(F [i]の[J] \)私は、分割された数を表し、すべてのプログラムとj係数について。
转移([I] [j]はfは= F [i]が[JI] -f [I-1] [JI] + [I-1] [J-(N + 1)] \ F)\
ための\(I <= \ SQRT {2K} \) 、それほど複雑である\(O(K \ SQRT K)\) 。
別の多項式EXPアプローチ:
Lnはこの式は、最後の再EXPのバックかもしれません。
我々はそれを知っています:
\(LN(1 + X)\)
$ = \ int型〜LN(1 + x)の」$
\(= \ INT〜{1 \ X + 1を超える} \)
\(= \ INT〜\ sum_ {I> = 0}( - 1)^ IX ^ iは\)
\(= \ sum_ {I> = 1} {( - 1)^ {I-1}のx ^ iは上\} \)
\(ANS = EXP(\ sum_ {i = 1} ^ N(LN(1-x ^ I)-ln(1-X)))[X ^ K] \)
\(LN(1-x ^ I)= \ sum_ {J> = 1} {( - 1)^ {(J-1)は、i}、X ^ {IJ} \ Jオーバー} \)
だから、暴力は便利なアイテムの唯一の高調波シリーズを展開します。
\(LN(1-X) \) 暴力起動共感がn倍させることができる後。
複雑\(O(N〜N-ログ)\)が、MTTを書き、とても遅い巨大な、と書くことが困難を実行します。
コード:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;
const int mo = 1e9 + 7;
ll ksm(ll x, ll y) {
ll s = 1;
for(; y; y /= 2, x = x * x % mo)
if(y & 1) s = s * x % mo;
return s;
}
const int N = 1e5 + 5;
int n, k, m;
ll fac[N * 2], nf[N * 2];
ll f[450][N];
ll g[N];
void calc(int n) {
fac[0] = 1; fo(i, 1, n) fac[i] = fac[i - 1] * i % mo;
nf[n] = ksm(fac[n], mo - 2); fd(i, n, 1) nf[i - 1] = nf[i] * i % mo;
}
ll C(int n, int m) {
return fac[n] * nf[n - m] % mo * nf[m] % mo;
}
int main() {
freopen("b.in", "r", stdin);
freopen("b.out", "w", stdout);
calc(200000);
scanf("%d %d", &n, &k);
m = sqrt(2 * k);
f[0][0] = 1;
fo(i, 1, m) {
fo(j, i, k) {
f[i][j] = f[i][j - i] - f[i - 1][j - i];
if(j >= n + 1) f[i][j] += f[i - 1][j - (n + 1)];
f[i][j] %= mo;
}
}
ll ans = 0;
fo(i, 0, k) {
fo(j, 0, m) g[i] += f[j][i];
g[i] %= mo;
ans += g[i] * fac[n - 1 + (k - i)] % mo * nf[k - i] % mo;
}
ans = (ans % mo * nf[n - 1] % mo + mo) % mo;
pp("%lld\n", ans);
}