[洛谷P5205]【模板】多项式开根
题目大意:给你$n$项多项式$A(x)$,求出$B(x)$满足$B^2(x)\equiv A(x)\pmod{x^n}$
题解:考虑已经求出$B_0(x)$满足$B_0^2(x)\equiv A(x)\pmod{x^{\lceil\frac n 2\rceil}}$
$$
B(x)-B_0(x)\equiv0\pmod{x^{\lceil\frac n 2\rceil}}\\
B^2(x)−2B(x)B_0(x)+B_0^2(x)≡0\pmod{x^n}\\
A(x)-2B(x)B_0(x)+B_0^2(x)≡0\pmod{x^n}\\
B(x)\equiv\dfrac{A(x)+B_0^2(x)}{2B_0(x)}\pmod{x^n}\\
$$
update:(2019-2-10)
$$
B(x)\equiv\dfrac{A(x)+B_0^2(x)}{2B_0(x)}\pmod{x^n}\\
B(x)\equiv\dfrac{A(x)}{2B_0(x)}+\dfrac{B_0(x)}2\pmod{x^n}\\
$$
发现$\dfrac{B_0(x)}2$只会影响$B(x)$数组的前半部分(即$\pmod{x^{\lceil\frac n2\rceil}}$的部分),但是$B(x)\equiv B_0(x)\pmod{x^{\lceil\frac n2\rceil}}$,所以可以不做考虑,直接把$B_0(x)$拉过来
卡点:求$INV$时注意清空数组,防止因为$B$数组不干净导致出锅
C++ Code:
#include <algorithm>
#include <cctype>
#include <cstdio>
#define maxn 262144
const int mod = 998244353, __2 = mod + 1 >> 1; namespace std {
struct istream {
#define M (1 << 21 | 3)
char buf[M], *ch = buf - 1;
inline istream() { fread(buf, 1, M, stdin); }
inline istream& operator >> (int &x) {
while (isspace(*++ch));
for (x = *ch & 15; isdigit(*++ch); ) x = x * 10 + (*ch & 15);
return *this;
}
#undef M
} cin;
struct ostream {
#define M (1 << 21 | 3)
char buf[M], *ch = buf - 1;
inline ostream& operator << (int x) {
if (!x) {*++ch = '0'; return *this;}
static int S[20], *top; top = S;
while (x) {*++top = x % 10 ^ 48; x /= 10;}
for (; top != S; --top) *++ch = *top;
return *this;
}
inline ostream& operator << (const char x) {*++ch = x; return *this;}
inline ~ostream() { fwrite(buf, 1, ch - buf + 1, stdout); }
#undef M
} cout;
} namespace Math {
inline int pw(int base, int p) {
static int res;
for (res = 1; p; p >>= 1, base = static_cast<long long> (base) * base % mod) if (p & 1) res = static_cast<long long> (res) * base % mod;
return res;
}
inline int inv(int x) { return pw(x, mod - 2); }
} inline void reduce(int &x) { x += x >> 31 & mod; }
inline void clear(register int *l, const int *r) {
if (l >= r) return ;
while (l != r) *l++ = 0;
} namespace Poly {
#define N maxn
int lim, s, rev[N];
int Wn[N + 1]; inline void init(const int n) {
lim = 1, s = -1; while (lim < n) lim <<= 1, ++s;
for (register int i = 1; i < lim; ++i) rev[i] = rev[i >> 1] >> 1 | (i & 1) << s;
const int t = Math::pw(3, (mod - 1) / lim);
*Wn = 1; for (register int *i = Wn; i != Wn + lim; ++i) *(i + 1) = static_cast<long long> (*i) * t % mod;
}
inline void FFT(int *A, const int op = 1) {
for (register int i = 1; i < lim; ++i) if (i < rev[i]) std::swap(A[i], A[rev[i]]);
for (register int mid = 1; mid < lim; mid <<= 1) {
const int t = lim / mid >> 1;
for (register int i = 0; i < lim; i += mid << 1)
for (register int j = 0; j < mid; ++j) {
const int X = A[i + j], Y = static_cast<long long> (A[i + j + mid]) * Wn[t * j] % mod;
reduce(A[i + j] += Y - mod), reduce(A[i + j + mid] = X - Y);
}
}
if (!op) {
const int ilim = Math::inv(lim);
for (register int *i = A; i != A + lim; ++i) *i = static_cast<long long> (*i) * ilim % mod;
std::reverse(A + 1, A + lim);
}
} void INV(int *A, int *B, int n) {
if (n == 1) { *B = Math::inv(*A); return ; }
const int len = n + 1 >> 1;
INV(A, B, len); init(len * 3);
static int C[N], D[N];
std::copy(A, A + n, C); clear(C + n, C + lim);
std::copy(B, B + len, D); clear(D + len, D + lim);
FFT(D), FFT(C);
for (register int i = 0; i < lim; ++i) D[i] = (2 - static_cast<long long> (D[i]) * C[i] % mod + mod) * D[i] % mod;
FFT(D, 0); std::copy(D + len, D + n, B + len);
}
void SQRT(int *A, int *B, int n) {
if (n == 1) { *B = 1; return ; }
static int C[N], D[N];
const int len = n + 1 >> 1;
SQRT(A, B, len);
INV(B, D, n), clear(D + n, D + lim);
std::copy(A, A + n, C); clear(C + n, C + lim);
FFT(C), FFT(D);
for (register int i = 0; i < lim; ++i) D[i] = static_cast<long long> (C[i]) * D[i] % mod * __2 % mod;
FFT(D, 0); std::copy(D + len, D + n, B + len);
}
#undef N
} int n, A[maxn], B[maxn];
int main() {
std::cin >> n;
for (int i = 0; i < n; ++i) std::cin >> A[i];
Poly::SQRT(A, B, n);
for (int i = 0; i < n; ++i) std::cout << B[i] << ' ';
std::cout << '\n';
return 0;
}
[洛谷P5205]【模板】多项式开根的更多相关文章
- 洛谷.3803.[模板]多项式乘法(FFT)
题目链接:洛谷.LOJ. FFT相关:快速傅里叶变换(FFT)详解.FFT总结.从多项式乘法到快速傅里叶变换. 5.4 又看了一遍,这个也不错. 2019.3.7 叕看了一遍,推荐这个. #inclu ...
- 洛谷.3803.[模板]多项式乘法(NTT)
题目链接:洛谷.LOJ. 为什么和那些差那么多啊.. 在这里记一下原根 Definition 阶 若\(a,p\)互质,且\(p>1\),我们称使\(a^n\equiv 1\ (mod\ p)\ ...
- 洛谷.4512.[模板]多项式除法(NTT)
题目链接 多项式除法 & 取模 很神奇,记录一下. 只是主要部分,更详细的和其它内容看这吧. 给定一个\(n\)次多项式\(A(x)\)和\(m\)次多项式\(D(x)\),求\(deg(Q) ...
- 洛谷.4238.[模板]多项式求逆(NTT)
题目链接 设多项式\(f(x)\)在模\(x^n\)下的逆元为\(g(x)\) \[f(x)g(x)\equiv 1\ (mod\ x^n)\] \[f(x)g(x)-1\equiv 0\ (mod\ ...
- 洛谷 P4512 [模板] 多项式除法
题目:https://www.luogu.org/problemnew/show/P4512 看博客:https://www.cnblogs.com/owenyu/p/6724611.html htt ...
- 洛谷 P4238 [模板] 多项式求逆
题目:https://www.luogu.org/problemnew/show/P4238 看博客:https://www.cnblogs.com/xiefengze1/p/9107752.html ...
- 洛谷P2293 高精开根
锣鼓2293 写完了放代码 应该没什么思维难度 ———————————————————————————————————————————————————————— python真香 m=input() ...
- P5277 【模板】多项式开根(加强版)(bsgs or Cipolla)
题面 传送门 题解 首先你得会多项式开根->这里 其次你得会解形如 \[x^2\equiv a \pmod{p}\] 的方程 这里有两种方法,一个是\(bsgs\)(这里),还有一种是\(Cip ...
- FFT模板 生成函数 原根 多项式求逆 多项式开根
FFT #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
随机推荐
- 使用CRF做命名实体识别(三)
摘要 本文主要是对近期做的命名实体识别做一个总结,会给出构造一个特征的大概思路,以及对比所有构造的特征对结构的影响.先给出我最近做出来的特征对比: 目录 整体操作流程 特征的构造思路 用CRF++训练 ...
- Appium(Python)驱动手机Chrome浏览器
手机Chrome浏览器访问淘宝H5与在电脑上访问淘宝H5是一摸一样的: 第一种方法: 直接在电脑Chrome浏览器上打开F12: 第二种方法: 手机连接电脑后, 在手机Chrome浏览器上打开淘宝H5 ...
- python处理dict转json,字符串中存在空格问题,导致url编码时,存在多余字符
在进行urlencode转换请求的参数时,一直多出一个空格,导致请求参数不正确,多了一个空格,解决方法一种是将dict中key-value键值对的value直接定义为字符串,另一种是value仍然为字 ...
- 软件测试的基础-摘自《selenium实践-基于电子商务平台》
软件测试的方法 一.等价类划分法 等价类划分法是把所有可能的输入数据,即程序的输入域划分成若干部分(子集),然后从每一个子集中选取少量具有代表性的数据作为测试用例. 有两种不同的情况:有效等价和无效等 ...
- 孵化器使用Office365的场景及收益
- https的主体过程
https其实就是基于SSL的http.加密后的http信息按理是不会被篡改和查看的. https的过程总体上是按照下面来进行的: 1.客户端发起请求,服务端返回一个SSL证书,证书里面有一公钥A. ...
- c# 读取xml文件 编写form
主要思想:xml保存控件的数据,c#读取出来并加以显示. 难点:1.控件有父容器和子控件的关系:2.控件事件的添加. 1.控件有父容器和子控件的关系: 可以用绝对坐标在xml文件中先读取子控件再读取父 ...
- c# windows service 程序
service服务程序:可以长时间运行可执行应用程序.没有用户界面.可以自动启动和手动启动.适用于在服务器上或需要干扰其他工作的用户可以在同一台计算机上长时间的运行此功能. C#创建service服务 ...
- HashMap get()返回值问题
问题描述:在进行mysql查询必要字段后,需要根据id进行es其它数据字段的查询拼接.使用HashMap以id为key 以查询过来的数据值为value. 代码如下: Map<String,Int ...
- Alpha 冲刺报告(4/10)
Alpha 冲刺报告(4/10) 队名:洛基小队 峻雄(组长) 已完成:继续行动脚本的编写 明日计划:尽量完成角色的移动 剩余任务:物品背包交互代码 困难:具体编码进展比较缓慢 ----------- ...