分式分解——2025.6.8 鲜花

分式分解——2025.6.8 鲜花

余命2:30
あ 生まれた
何をして生きようか
無限の可能性が広がる まだ8秒だ
あんなことできるかな
何にでもなれるかな
来るべき不幸から
目を背けながら
真面目に生きようか
小狡く生きようか
君を助けたい 蹴落としたい
どっちも自分だ
夢や恋はファストで
努力はつらいよね
本や映画は
あらすじだけでいいかな
余命2:30
余命2:30
「ありがとう」「さよなら」
「またね」をくり返して
もう45秒の春
余命2:30
使い捨てられる青
3分に満たない
替えが利く ぼくの命を
涙で消費しないでね
夢ってこんなもんか
恋ってこんなもんか
人生ってまるで
よくある歌みたいだな
1分以上過ぎて
「自分」を思い知って
だけど 悟るには まだまだ早いね
チクタク チクタク
もういない君を想う
1分前 描いた夢とは ほど遠いが
余命2:30
余命2:30
「よかった」「もうだめだ」
「まあいっか」をくり返して
1分45秒の秋
余命2:30
また一つ消える魔法
君のため?ぼくのため?
大袈裟に嘆く命を
どうか美化しすぎないでね
あの日 読み飛ばした
本や映画みたいに
ぼくの命も 短い歌になって
余命2:30でさよならでも
幸せだったと言わせて欲しいの
余命2:30
余命2:30
3分に満たない
もう終わる ぼくの命を
人事って思わないでね
あ

比较易。

未加说明则 \(x\) 是多项式的变量。

设分式形如 \(F = \frac 1{\prod\limits_i Q_i}\),我们想把他分解成 \(\sum\limits_i \frac{R_i}{Q_i}\),其中 \(\deg R_i < \deg Q_i\)

有:

\[\frac 1{\prod_i Q_i}=\sum_i \frac{R_i}{Q_i} \]

\[1=\sum_i \frac{\prod_j Q_j R_i}{Q_i} \]

考虑 \(\deg\) 的限制,我们对 \(Q_i\) 取模。

\[R_i=(\prod_{j != i} Q_j)^{-1} \bmod {Q_i} \]

这个东西用处只在于其形式,用来做类似 EI 营业日志 2020.5.20

正常的实现这个感觉都 \(n^2\log^2 n\sim n^3\) 了。

Upd:jijidawang 说 EI 已经 \(n\log^2 n\) 了,不过我不会

我们在 \(Q_i = 1 - a_ix\) 时给出一个更正常的 \(n ^ 2\) 做法。

考虑取模的意义,实际上是去掉其他项的贡献,我们用一个类似拉差的做法做到这个。

设原式

\[\sum\limits_i \frac{R_i}{1 - a_ix} \]

通分后 \(R_i\) 的限制

\[\sum\limits_i R_i \prod\limits_{j != i} (1 - a_jx) = 1 \]

我们取 \(x = \frac 1{a_k}\),容易发现此时所有 \(i \not= k\) 的项全等于 \(0\),所以此时有

\[R_i \prod\limits_{j != i} (1 - \frac{a_j}{a_i}) = 1 \]

即可解出

\[R_i = (\prod\limits_{j != i} (1 - \frac{a_j}{a_i})) ^ {-1} \]

例题:AT_abc241_h [ABC241Ex] Card Deck Score

直接整出生成函数

\[[x^m] \prod_{i = 1} ^ n \frac{1 - (a_ix_i)^{b_i}}{1 - a_ix_i} \]

考虑分子的系数直接 \(\mathcal{O}(n2^n)\) 枚举即可,重点在于分母的系数。

我们直接套用分式分解,将

\[\prod_{i = 1} ^ n \frac 1{1 - a_ix_i} \]

改写成

\[\sum\limits_i \frac{R_i}{1 - a_ix} \]

则可以 \(\mathcal{O}(n\log P)\)\(P = 998244353\) 为模数)求单次系数,将枚举分子的 \(2^n\) 个系数带入即可。

总复杂度是 \(\mathcal{O}(n2^n\log P)\) 的。

Code
/*
clear && g++ % -o %< -O2 -std=c++14 -DLOCAL -Wall -Wextra && time ./%< && size %<
clear && g++ % -o %< -O2 -std=c++14 -DLOCAL -Wall -Wextra -fsanitize=address,undefined -g && time ./%< && size %<
echo && cat in_out/out.out && echo
*/
#include <bits/stdc++.h>
using namespace std;
using llt = long long;
using llf = long double;
using ull = unsigned long long;
#define endl '\n'
#ifdef LOCAL
FILE *InFile = freopen("in_out/in.in", "r", stdin), *OutFile = freopen("in_out/out.out", "w", stdout);
#endif
 
const int N = 20, MOD = 998244353;
int n; llt _a[N], _b[N], tt[N], m;
int Fpw(int a, int b){
	int ans = 1;
	for(; b; a = 1ll * a * a % MOD, b >>= 1) if(b & 1) ans = 1ll * ans * a % MOD;
	return ans;
}
int Inv(int a){ return Fpw(a, MOD - 2); }

int main(){
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for(int i = 1; i <= n; ++i) cin >> _a[i] >> _b[i], _b[i] += 1, _a[i] %= MOD;
	for(int i = 1; i <= n; ++i){
		int s = 1, v = Inv(_a[i]);
		for(int j = 1; j <= n; ++j) if(j != i) s = s * (1 - v * _a[j] % MOD) % MOD;
		tt[i] = Inv(s);
	}
	llt ans = 0;
	for(int i = 0, cs = (1 << n) - 1; i <= cs; ++i){
		llt c = 0, t = 1;
		for(int j = 1; j <= n; ++j) if((i >> (j - 1)) & 1)
			c += _b[j], t = 1ll * t * -Fpw(_a[j], _b[j] % (MOD - 1)) % MOD;
		c = (m - c) % (MOD - 1); if(c < 0) continue;
		for(int j = 1; j <= n; ++j) ans = (ans + 1ll * t * Fpw(_a[j], c) % MOD * tt[j]) % MOD;
	}
	cout << (ans % MOD + MOD) % MOD;
}
P




posted @ 2025-06-08 21:48  xrlong  阅读(41)  评论(2)    收藏  举报

Loading