YZOI p278
赛时把正解复杂度算成 \(\mathcal{O}(n^{10000}\log V)\) 了遗憾离场了qwq,这里不赘述正解做法,给出一个赛后看到的爆标做法。
首先考虑每个位置的操作次数为 \(c_i = 3k + a_i, a_i \in [0, 2]\),总操作次数的限制是 \(N\),那么贡献就是 \(\frac{(\sum c_i)!}{\prod c_i!}\),即多重组合数。那么容易想到用 EGF 来刻画。
记 \([x^i]\hat F_j(x)\) 为 \(j\) 这个位置操作 \(i\) 次的方案数。
\[\hat F_j(x) = \sum\limits_{i \ge 0} \dfrac{x^{3i+a_j}}{(3i+a_i)!}
\]
\[=\sum\limits_{i \ge 0} [i \bmod 3 = a_j]\dfrac{x^i}{i!}
\]
\[\sum\limits_{i \ge 0}[3 \mid (i - a_j)] \dfrac{x^i}{i!}
\]
单位根反演得
\[\sum\limits_{i \ge 0}\dfrac{1}{3}\sum\limits_{k=0}^2 \omega_3^{k(i-a_j)}\dfrac{x^i}{i!}
\]
\[=\dfrac{1}{3}\sum\limits_{k=0}^2\dfrac{1}{\omega_3^{ka_j}}\sum\limits_{i\ge0}\omega_3^{ki}\dfrac{x^i}{i!}
\]
然后答案就是 \(\sum\limits_{i=0}^N [x^i]\hat G(x)\),其中 \(\hat G(x) = \prod \hat F(x)\)。
\[\hat G(x) = \prod\hat F(x)
\]
\[=\dfrac{1}{3^n}\prod\limits_{j=1}^n \sum\limits_{k=0}^2\dfrac{1}{\omega_3^{ka_j}}\sum\limits_{i\ge0}\omega_3^{ki}\dfrac{x^i}{i!}
\]
\[=\dfrac{1}{3^n}\prod\limits_{j=1}^n \sum\limits_{k=0}^2\omega_3^{-ka_j}e^{\omega_3^{ki}x}
\]
后面的部分直接展开,得到
\[e^x + \omega^{-a_i}e^{\omega x} + \omega^{-2a_i}e^{\omega^2x}
\]
那么若干个这种形式乘起来会得到若干 \(pe^{qx}\) 的形式,展开,
\[pe^{qx} = \sum\limits_{i \ge 0} \dfrac{pq^ix_i}{i!}
\]
对 EGF 的系数求前缀和:
\[\sum\limits_{i=0}^N pq^i=p\dfrac{q^{N+1}-1}{q-1}
\]
最后的系数用递推计算即可,时间复杂度 \(\mathcal{O}(n^3 \log mod)\)。
namespace Loop1st {
int n, a[15], cost[3];
char s[15], t[15];
ll m;
struct Complex {
ll x, y;
Complex(ll _x = 0, ll _y = 0): x(_x), y(_y) {}
Complex operator + (const Complex &A) const { return Complex((x + A.x) % mod, (y + A.y) % mod); }
void operator += (const Complex &A) { *this = *this + A; }
Complex operator * (const Complex &A) const { return Complex(((x * A.x - y * A.y) % mod + mod) % mod, (x * A.y + y * A.x) % mod); }
void operator *= (const Complex &A) { *this = *this * A; }
void operator = (const ll &A) { *this = Complex(A % mod, 0); }
} f[15][15], g[15][15];
const Complex w((mod - 1) >> 1, (mod + sq3) >> 1), w2((mod - 1) >> 1, (mod - sq3) >> 1);
ll qpow(ll a, ll b) {
ll res = 1;
for (; b; b >>= 1, a = a * a % mod) if (b & 1) res = res * a % mod;
return res;
}
ll inv(ll x) { return qpow(x, mod - 2); }
Complex inv(Complex A) {
ll div = inv((A.x * A.x + A.y * A.y) % mod);
return Complex(A.x * div % mod, (mod - A.y) * div % mod);
}
Complex qpow(Complex a, ll b) {
Complex res = 1;
if (b < 0) a = inv(a), b = -b;
for (; b; b >>= 1, a = a * a) if (b & 1) res = res * a;
return res;
}
Complex calc(Complex q, ll k) {
if (q.x == 1 && q.y == 0) return Complex(k + 1, 0);
return (qpow(q, k + 1) + Complex(mod - 1, 0)) * inv(q + Complex(mod - 1, 0));
}
void Main(int tc) {
cin >> s >> t >> cost[0] >> cost[1] >> cost[2] >> m;
n = strlen(s);
Complex ans(qpow(iv3, n), 0);
ll N = 0;
for (int i = 0; i < n; i++) {
while (s[i] != t[i]) {
m -= cost[s[i] - 'a'];
s[i] = 'a' + (s[i] - 'a' + 1) % 3;
a[i]++;
}
N += a[i];
}
if (m < 0) { cout << "0\n"; return ; }
N += m / (cost[0] + cost[1] + cost[2]) * 3;
f[0][0] = 1;
for (int i = 0; i < n; i++) {
memset(g, 0, sizeof g);
for (int j = 0; j <= i; j++) {
for (int k = 0; k <= i - j; k++) {
g[j + 1][k] += f[j][k];
g[j][k + 1] += qpow(w, -a[i]) * f[j][k];
g[j][k] += qpow(w, -2 * a[i]) * f[j][k];
}
}
memcpy(f, g, sizeof f);
}
Complex res;
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n - i; j++) {
Complex q = Complex(i, 0) + Complex(j, 0) * w + Complex(n - i - j, 0) * w2;
res += f[i][j] * calc(q, N);
}
}
ans *= res;
cout << ans.x << '\n';
}
}

浙公网安备 33010602011771号