This documentation is automatically generated by online-judge-tools/verification-helper
#include "fps/mod_pow.hpp"
#ifndef KK2_FPS_MOD_POW_HPP
#define KK2_FPS_MOD_POW_HPP 1
#include <cassert>
namespace kk2 {
// return f ^ k mod g
template <class FPS, class mint = typename FPS::value_type, class T>
FPS mod_pow(T k, const FPS &f, const FPS &g) {
// assert(!is_signed_v<T> || k >= 0);
assert(!g.empty());
auto inv = g.rev().inv();
auto quo = [&](const FPS &poly) {
if (poly.size() < g.size()) return FPS{};
int n = poly.size() - g.size() + 1;
return (poly.rev().pre(n) * inv.pre(n)).pre(n).rev();
};
FPS res{1}, b(f);
while (k) {
if (k & 1) {
res *= b;
res -= quo(res) * g;
res.shrink();
}
b *= b;
b -= quo(b) * g;
b.shrink();
k >>= 1;
}
return res;
}
} // namespace kk2
#endif // KK2_FPS_MOD_POW_HPP
#line 1 "fps/mod_pow.hpp"
#include <cassert>
namespace kk2 {
// return f ^ k mod g
template <class FPS, class mint = typename FPS::value_type, class T>
FPS mod_pow(T k, const FPS &f, const FPS &g) {
// assert(!is_signed_v<T> || k >= 0);
assert(!g.empty());
auto inv = g.rev().inv();
auto quo = [&](const FPS &poly) {
if (poly.size() < g.size()) return FPS{};
int n = poly.size() - g.size() + 1;
return (poly.rev().pre(n) * inv.pre(n)).pre(n).rev();
};
FPS res{1}, b(f);
while (k) {
if (k & 1) {
res *= b;
res -= quo(res) * g;
res.shrink();
}
b *= b;
b -= quo(b) * g;
b.shrink();
k >>= 1;
}
return res;
}
} // namespace kk2