参考了 cmd 的多项式计数杂谈,拜谢。
考虑题目给定的其实就是 \(x\) 分布的 PGF \(F(x)\)。那么令 \(F_i(x)\) 表示操作了 \(i\) 轮后 \(x\) 的 PGF,则 \(F_0(x)=F(x)\)。
考虑一次操作对 \(x\) 的影响,若操作成了 \(k\):
\[[x^k]F_{i}(x)=\sum\limits_{j=k}[x^j]\frac{F_{i-1}(x)}{j+1} \]于是:
\[\begin{aligned}F_i(x)&=\sum\limits_{k}x^k\sum\limits_{j=k}[x^j]\frac{F_{i-1}(x)}{j+1}\\&=\sum\limits_{j}[x^j]\frac{F_{i-1}(x)}{j+1}\sum\limits_{k=0}^jx^k\\&=\sum\limits_{j}[x^j]\frac{F_{i-1}(x)}{j+1}\cdot\frac{x^{j+1}-1}{x-1}\\&=\frac{1}{x-1}\sum\limits_{j}\frac{x^{j+1}-1}{j+1}[x^j]F_{i-1}(x)\end{aligned} \]这个分式好像有点眼熟,回忆幼数课本:
\[\int x^jdx=\frac{x^{j+1}}{j+1} \]那么把 \(1\) 当成 \(1^{j+1}\):
\[\begin{aligned}F_i(x)&=\frac{1}{x-1}\sum\limits_{j}\frac{x^{j+1}-1}{j+1}[x^j]F_{i-1}(x)\\&=\frac{1}{x-1}\sum\limits_j[x^j]F_{i-1}(x)\int_1^xt^jdt\\&=\frac{1}{x-1}\int_1^x\left(\sum\limits_{j}[x^j]F_{i-1}(x)t^j\right)dt\\&=\frac{1}{x-1}\int_1^xF_{i-1}(t)dt\end{aligned} \]这个积分的下限为 \(1\),尝试换元转不定积分。令 \(z=x-1\):
\[\begin{aligned}F_i(x)&=F_i(z+1)\\&=\frac{1}{z}\int _0^{z}F_{i-1}(t+1)d(t+1)\end{aligned} \]再次换元,令 \(G_i(x)=F_i(x+1)\):
\[\begin{aligned}G_i(x)&=\frac{1}{x}\int_0^zG_{i-1}(t)dt\\&=\frac{1}{x}\int G_{i-1}(z)dz \\&=\frac{1}{x}\sum\limits_j[x^j]G_{i-1}(x)\frac{x^{j+1}}{j+1}\\&=\sum\limits_j[x^j]G_{i-1}(x)\frac{x^j}{j+1}\end{aligned} \]比较左右系数,得到 \([x^j]G_{i}(x)=\frac{[x^j]G_{i-1}(x)}{j+1}\),这是个等比数列,于是 \([x^j]G_i(x)=(i+1)^{-j}[x^j]G_0(i)\),现在考虑如何快速求出 \(G(x)=G_0(x)=F(x+1)\):
\[\begin{aligned}G(x)&=F(x+1)\\&=\sum\limits_{i}[x^i]F(x)(x+1)^i\\&=\sum\limits_i[x^i]F(x)\sum\limits_{j=0}^i\dbinom{i}{j}x_j\\&=\sum\limits_{j}x^j\sum\limits_{i=j}[x^i]F(x)\dbinom{i}{j}\end{aligned} \]提取 \(G(x)\) 的系数:
\[\begin{aligned}[x^j]G(x)&=\sum\limits_{i=j}[x^i]F(x)\dbinom{i}{j}\\&=\sum\limits_{i=j}\frac{i!}{j!(i-j)!}[x^i]F(x)\\&=\frac{1}{j!}\sum\limits_{i=j}i![x^i]F(x)\cdot \frac{1}{(i-j)!}\end{aligned} \]这就变成了显然的差卷积形式,直接做就行了。
得到 \(G_n(x)\) 之后,就可以二项式反演得到 \(F_n(x)\):
\[\begin{aligned}[x^j]G_m(x)&=\sum\limits_{i=j}[x^i]F_m(x)\dbinom{i}{j}\end{aligned} \]\[\begin{aligned}[x^j]F_m(x)&=\sum\limits_{i=j}[x^i]G_m(x)(-1)^{i-j}\dbinom{i}{j}\end{aligned} \]同样的套路,拆开组合数即可。
复杂度 \(O(n\log n)\)。
// Problem: E. Perpetual Subtraction
// Contest: Codeforces - VK Cup 2018 - Round 1
// URL: https://codeforces.com/problemset/problem/923/E
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
namespace vbzIO {
char ibuf[(1 << 20) + 1], *iS, *iT;
#if ONLINE_JUDGE
#define gh() (iS == iT ? iT = (iS = ibuf) + fread(ibuf, 1, (1 << 20) + 1, stdin), (iS == iT ? EOF : *iS++) : *iS++)
#else
#define gh() getchar()
#endif
#define mt make_tuple
#define mp make_pair
#define fi first
#define se second
#define pc putchar
#define pb emplace_back
#define ins insert
#define era erase
typedef long long ll;
typedef tuple<int, int, int> tu3;
typedef pair<int, int> pi;
inline int rd() {
char ch = gh();
int x = 0;
bool t = 0;
while (ch < '0' || ch > '9') t |= ch == '-', ch = gh();
while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gh();
return t ? ~(x - 1) : x;
}
inline ll rdl() {
char ch = gh();
ll x = 0;
bool t = 0;
while (ch < '0' || ch > '9') t |= ch == '-', ch = gh();
while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gh();
return t ? ~(x - 1) : x;
}
inline void wr(int x) {
if (x < 0) x = ~(x - 1), putchar('-');
if (x > 9) wr(x / 10);
putchar(x % 10 + '0');
}
}
using namespace vbzIO;
const int P = 998244353;
const int N = 5e5 + 500;
const int G = 114514;
int n, m, len, lim;
int f[N], g[N], fac[N], ifac[N], inv[N], tr[N];
int Add(int x, int y) { x += y; return (x >= P) ? (x - P) : x; }
int Mul(int x, int y) { return 1ll * x * y % P; }
int qpow(int p, int q) {
int res = 1;
for (; q; q >>= 1, p = Mul(p, p))
if (q & 1) res = Mul(res, p);
return res;
}
const int iG = qpow(G, P - 2);
void init(int lim) {
fac[0] = ifac[0] = inv[1] = 1;
for (int i = 1; i <= lim; i++) {
if (i > 1) inv[i] = Mul(inv[P % i], P - P / i);
fac[i] = Mul(fac[i - 1], i), ifac[i] = Mul(ifac[i - 1], inv[i]);
}
}
int C(int n, int m) {
if (n < m || m < 0) return 0;
return Mul(fac[n], Mul(ifac[m], ifac[n - m]));
}
void NTT(int *f, int op) {
for (int i = 0; i < len; i++)
if (i < tr[i]) swap(f[i], f[tr[i]]);
for (int o = 2, k = 1; k < len; o <<= 1, k <<= 1) {
int tg = qpow(~op ? G : iG, (P - 1) / o);
for (int i = 0; i < len; i += o) {
for (int j = 0, w = 1; j < k; j++, w = Mul(w, tg)) {
int x = f[i + j], y = Mul(w, f[i + j + k]);
f[i + j] = Add(x, y), f[i + j + k] = Add(x, P - y);
}
}
}
if (~op) return;
int iv = qpow(len, P - 2);
for (int i = 0; i < len; i++)
f[i] = Mul(f[i], iv);
}
void Mul(int *f, int *g, int *h) {
static int tf[N], tg[N];
len = 1, lim = 0;
while (len < (n + 1) << 1) len <<= 1, lim++;
for (int i = 1; i < len; i++)
tr[i] = (tr[i >> 1] >> 1) | ((i & 1) << (lim - 1));
for (int i = 0; i <= n; i++) tf[i] = f[i], tg[i] = g[i];
for (int i = n + 1; i < len; i++) tf[i] = tg[i] = 0;
NTT(tf, 1), NTT(tg, 1);
for (int i = 0; i < len; i++)
tf[i] = Mul(tf[i], tg[i]);
NTT(tf, -1);
for (int i = 0; i <= n; i++) h[i] = tf[i];
}
int main() {
n = rd(), m = rdl() % (P - 1), init(n);
for (int i = 0; i <= n; i++)
f[i] = Mul(rd(), fac[i]);
reverse(f, f + n + 1);
for (int i = 0; i <= n; i++)
g[i] = ifac[i];
Mul(f, g, g);
reverse(g, g + n + 1);
for (int i = 0; i <= n; i++)
g[i] = Mul(g[i], ifac[i]);
for (int i = 0; i <= n; i++)
g[i] = Mul(g[i], qpow(qpow(i + 1, P - 2), m));
for (int i = 0; i <= n; i++)
g[i] = Mul(g[i], fac[i]);
reverse(g, g + n + 1);
for (int i = 0; i <= n; i++)
f[i] = Mul(((i & 1) ? (P - 1) : 1), ifac[i]);
Mul(f, g, f);
reverse(f, f + n + 1);
for (int i = 0; i <= n; i++)
wr(Mul(f[i], ifac[i])), pc(' ');
return 0;
}
标签:ch,frac,limits,CF923E,sum,Perpetual,int,Subtraction,aligned
From: https://www.cnblogs.com/Ender32k/p/17578514.html