高级操作,感觉非常神仙。

题目中的字母太难懂了,重新定义一下。

$$A(x) = B(x) * C(x) + D(x)$$

其中,$A(x)$的次数是$n$,$B(x)$的次数是$m$,$A, B$都已知,要求$C$的次数是$n - m$,$D$的次数小于$m$。

定义一种操作:

如果$A$的次数为$n$,那么

$$A_R(x) = x^nA(\frac{1}{x})$$

其实就是把一个多项式各项系数翻转过来。

比如$A(x) = x^3 + 2x^2 + 3x + 5$,有

$$A_R(x) = 5x^3 + 3x^2 + 2x + 1$$

有了这个操作之后就可以变魔术了。

发现这个$D(x)$很难受,想办法把它搞掉。

$$A(x) = B(x) * C(x) + D(x)$$

$$A(\frac{1}{x}) = B(\frac{1}{x})C(\frac{1}{x}) + D(\frac{1}{x})$$

两边乘上$x^n$,

$$x^nA(\frac{1}{x}) = x^mB(\frac{1}{x})x^{n - m}C(\frac{1}{x}) + x^{n - m + 1} * x^{m - 1}D(\frac{1}{x})$$

$$A_R(x) = B_R(x)C_R(x) + x^{n - m + 1} D_R(x)$$

两边模上$x^{n - m + 1}$,

$$A_R(x) \equiv B_R(x)C_R(x) (\mod x^{n - m + 1}) $$

其实就是求逆了呀。

求出$C(x)$之后只要重新算一遍多项式乘法减掉就可以算出$D(x)$了。

时间复杂度$O(nlogn)$。

Code:

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef vector <ll> poly; const int N = 1e5 + ; namespace Poly {
const int L = << ;
const ll P = 998244353LL; int lim, pos[L]; inline void deb(poly c) {
for (int i = ; i < (int)c.size(); i++)
printf("%lld%c", c[i], " \n"[i == (int)c.size() - ]);
} template <typename T>
inline void inc(T &x, T y) {
x += y;
if (x >= P) x -= P;
} template <typename T>
inline void sub(T &x, T y) {
x -= y;
if (x < ) x += P;
} inline ll fpow(ll x, ll y) {
ll res = ;
for (; y > ; y >>= ) {
if (y & ) res = res * x % P;
x = x * x % P;
}
return res;
} inline void prework(int len) {
int l = ;
for (lim = ; lim < len; lim <<= , ++l);
for (int i = ; i < lim; i++)
pos[i] = (pos[i >> ] >> ) | ((i & ) << (l - ));
} inline void ntt(poly &c, int opt) {
c.resize(lim, );
for (int i = ; i < lim; i++)
if (i < pos[i]) swap(c[i], c[pos[i]]);
for (int i = ; i < lim; i <<= ) {
ll wn = fpow(, (P - ) / (i << ));
if (opt == -) wn = fpow(wn, P - );
for (int len = i << , j = ; j < lim; j += len) {
ll w = ;
for (int k = ; k < i; k++, w = w * wn % P) {
ll x = c[j + k], y = w * c[j + k + i] % P;
c[j + k] = (x + y) % P, c[j + k + i] = (x - y + P) % P;
}
}
} if (opt == -) {
ll inv = fpow(lim, P - );
for (int i = ; i < lim; i++) c[i] = c[i] * inv % P;
}
} inline poly mul(const poly x, const poly y) {
poly u = x, v = y, res;
prework(x.size() + y.size() - );
ntt(u, ), ntt(v, );
for (int i = ; i < lim; i++) res.push_back(u[i] * v[i] % P);
ntt(res, -);
res.resize(x.size() + y.size() - );
return res;
} poly getInv(poly x, int len) {
x.resize(len, );
if (len == ) {
poly res;
res.push_back(fpow(x[], P - ));
return res;
} poly y = getInv(x, (len + ) >> ); prework(len << );
poly u = x, v = y, res;
ntt(u, ), ntt(v, );
for (int i = ; i < lim; i++) res.push_back(v[i] * ((2LL - u[i] * v[i] % P + P) % P) % P);
ntt(res, -); res.resize(len, );
return res;
} inline poly getDiv(poly x, poly y) {
poly u = x, v = y, res; reverse(u.begin(), u.end());
reverse(v.begin(), v.end());
// deb(u), deb(v); int len = x.size() - y.size() + ;
u.resize(len, ), v.resize(len, ); // deb(u), deb(v); res = getInv(v, len); // deb(res); res = mul(u, res);
res.resize(len);
// deb(u); reverse(res.begin(), res.end()); return res;
} inline poly getRest(poly x, poly y) {
poly u = x, v = y, res = getDiv(x, y); v = mul(v, res);
res = u;
int len = max(u.size(), v.size());
res.resize(len, ), v.resize(len, );
for (int i = ; i < len; i++) res[i] = (res[i] - v[i] + P) % P; for (; !res.empty() && !res[res.size() - ]; res.pop_back());
return res;
} } using Poly :: getDiv;
using Poly :: getRest; template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for (; ch > ''|| ch < ''; ch = getchar())
if (ch == '-') op = -;
for (; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} int main() {
int n, m;
read(n), read(m);
++n, ++m; poly x, y;
x.resize(n, ), y.resize(m, );
for (int i = ; i < n; i++) read(x[i]);
for (int i = ; i < m; i++) read(y[i]); poly u = getDiv(x, y), v = getRest(x, y);
for (int i = ; i < (int)u.size(); i++)
printf("%lld%c", u[i], " \n"[i == (int)u.size() - ]);
for (int i = ; i < (int)v.size(); i++)
printf("%lld%c", v[i], " \n"[i == (int)v.size() - ]); return ;
}

最新文章

  1. 针对web高并发量的处理
  2. LA 4329 ping-pong树状数组
  3. Swift入门篇-结构体
  4. 招聘一个靠谱的 iOS程序员
  5. spoj 227
  6. c++11 lambda递归调用写法
  7. php/java bridge
  8. MVC过滤器基本使用
  9. mysql关闭/启用外键约束
  10. Java8新特性interface中的static方法和default方法
  11. uvm设计分析——field automation
  12. 【转】使用 Android 的日志工具LogCat
  13. Greenplum-cc-web监控软件安装时常见错误
  14. 什么是代码?code?
  15. LeetCode——Best Time to Buy and Sell Stock IV
  16. 简述对Vuex的理解
  17. winform布局 FlowLayoutPanel的控件
  18. 【OpenCV-Python】-图像阀值
  19. DotNet 学习笔记 OWIN
  20. 【转】Python爬虫(1)_基本原理

热门文章

  1. 20155226 2016-2017-2 《Java程序设计》第8周学习总结
  2. streamsets microservice pipeline 试用
  3. Trie树学习1
  4. html5 data属性的使用
  5. 从 Excel 表格粘贴到 浏览器表格中
  6. 【转】linux中inittab文件详解
  7. CCFlow SDK模式开发(有比较详细的代码,以服务的形式与ccflow数据库进行数据交互)
  8. linux Posix 信号量 一
  9. jmeter 目录内容分布
  10. Bootstrap-CL:多媒体对象