分式分解——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\)。
有:
考虑 \(\deg\) 的限制,我们对 \(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\) 做法。
考虑取模的意义,实际上是去掉其他项的贡献,我们用一个类似拉差的做法做到这个。
设原式
通分后 \(R_i\) 的限制
我们取 \(x = \frac 1{a_k}\),容易发现此时所有 \(i \not= k\) 的项全等于 \(0\),所以此时有
即可解出
例题:AT_abc241_h [ABC241Ex] Card Deck Score
直接整出生成函数
考虑分子的系数直接 \(\mathcal{O}(n2^n)\) 枚举即可,重点在于分母的系数。
我们直接套用分式分解,将
改写成
则可以 \(\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
本文来自博客园,作者:xrlong,转载请注明原文链接:https://www.cnblogs.com/xrlong/p/18919842
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。