手动博客搬家: 本文发表于20181125 13:21:46, 原地址https://blog.csdn.net/suncongbo/article/details/84485718

题目链接: https://www.luogu.org/problemnew/show/P4238

题意: 给定\(n\)次多项式\(A(x)\), 求\(n\)次多项式\(B(x)\)满足\(B(x)A(x)\equiv 1(\mod x^n)\)

题解:

DFT,每个数对\(998244353\)求逆元。IDFT回来。

发现,错了。

为什么呢?

因为要对\(x^n\)取模。

例如,\(1-x\)在模\(x^2\)意义下的逆元是\(1+x\), 但是在实际上逆元是\(1+x+x^2+x^3+...\), 是无穷和式。

所以此路不通。

考虑求解多项式问题的常用方法——分治法。

设已求\(B_0(x)\)满足\(B_0(x)A(x)\equiv 1(\mod x^n)\), 现要求\(B(x)\)满足\(B(x)A(x)\equiv 1(\mod x^{2n})\)

显然有\(B(x)-B_0(x)\equiv 0(\mod x^n)\)

为了凑出\(x^{2n}\)两边平方得

\(B^2(x)-2B_0(x)B(x)+B_0^2(x)\equiv 0(\mod x^{2n})\)

如何求\(B\)呢?因为\(A(x)B(x)\equiv 0(\mod x^{2n})\), 我们将式子两边同乘\(A(x)\)

\(A(x)B(x)B(x)-2B_0(x)A(x)B(x)+A(x)B_0^2(x)\equiv 0(\mod x^{2n})\)

\(B(x)\equiv 2B_0(x)-A(x)B_0^2(x) (\mod x^{2n})\)

右边的式子FFT计算即可。

时间复杂度?

\(T(n)=T(\frac{n}{2})+O(n\log n)\)

\(T(n)=O(n\log n)\).

常数?首先隐藏在递归复杂度背后有一个\(2\)倍常数。

然后我们把两个多项式相乘需要\(3\)次FFT, 三个就要\(6\)次。

因此常数为\(12\)倍。

如何优化?

\(IDFT(DFT(IDFT(DFT(A)\times DFT(B_0)))\times DFT(B_0))\)

变成\(IDFT(DFT(A)\times DFT^2(B_0)\)

\(3\)次即可!

常数变为\(6\)倍。

UPD: 关于这里的常数问题: 因为我递归里DFT的范围是\(2n\),最终的复杂度是\(T(2n) = 6(2n)\log (2n)\), 因此我认为应为\(12\)倍常数。

空间?空间复杂度\(O(n)\), 但是要开\(4d\)的数组,其中\(d\)是\(>n\)的最小的\(2\)的幂。

代码

因为FFT数组清零等原因代码(对我来说)很难写。

贴一下我刚刚写的版本吧,还算是比较简单。

(话说怎么CSDN突然傲娇了啊。。缩进变成1格??)

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define llong long long
#define ldouble long double
#define uint unsigned int
#define ullong unsigned long long
#define udouble unsigned double
#define uldouble unsigned long double
#define modinc(x) {if(x>=P) x-=P;}
#define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define piiii pair<pair<int,int>,pair<int,int> >
#define pli pair<llong,int>
#define pll pair<llong,llong>
#define Memset(a,x) {memset(a,x,sizeof(a));}
using namespace std; const int N = 1<<19;
const int P = 998244353;
const int LGN = 19;
const int G = 3;
llong a[N+3];
llong b[N+3];
llong tmp1[N+3],tmp2[N+3],tmp3[N+3],tmp4[N+3],tmp5[N+3],tmp6[N+3];
int id[N+2];
int n; void initid(int _len)
{
id[0] = 0;
for(int i=1; i<(1<<_len); i++) id[i] = (id[i>>1]>>1)|((i&1)<<(_len-1));
} llong quickpow(llong x,llong y)
{
llong cur = x,ret = 1ll;
for(int i=0; y; i++)
{
if(y&(1ll<<i))
{
y-=(1ll<<i); ret = ret*cur%P;
}
cur = cur*cur%P;
}
return ret;
}
llong mulinv(llong x) {return quickpow(x,P-2);} void ntt(int dgr,int coe,llong poly[],llong ret[])
{
int len = 0; for(int i=0; i<=LGN; i++) if((1<<i)==dgr) {len = i; break;}
initid(len); for(int i=0; i<dgr; i++) ret[i] = 0ll;
for(int i=0; i<dgr; i++) ret[i] = poly[i];
for(int i=0; i<dgr; i++) if(i<id[i]) swap(ret[i],ret[id[i]]);
for(int i=1; i<=(dgr>>1); i<<=1)
{
llong tmp = quickpow(G,(P-1)/(i<<1));
if(coe==-1) tmp = mulinv(tmp);
for(int j=0; j<dgr; j+=(i<<1))
{
llong expn = 1ll;
for(int k=0; k<i; k++)
{
llong x = ret[j+k],y = (expn*ret[j+i+k])%P;
ret[j+k] = x+y; modinc(ret[j+k]);
ret[j+i+k] = x-y+P; modinc(ret[j+i+k]);
expn = (expn*tmp)%P;
}
}
}
} void polyinv(int dgr,llong poly[],llong ret[])
{
for(int i=0; i<dgr; i++) ret[i] = 0ll;
ret[0] = mulinv(poly[0]);
for(int i=1; i<=(dgr>>1); i<<=1)
{
for(int j=0; j<(i<<2); j++) tmp1[j] = j<i ? ret[j] : 0ll;
for(int j=0; j<(i<<2); j++) tmp2[j] = j<(i<<1) ? poly[j] : 0ll;
ntt((i<<2),1,tmp1,tmp3); ntt((i<<2),1,tmp2,tmp4);
for(int j=0; j<(i<<2); j++) tmp5[j] = tmp3[j]*tmp3[j]%P*tmp4[j]%P;
ntt((i<<2),-1,tmp5,tmp6); llong tmp = mulinv(i<<2);
for(int j=0; j<(i<<2); j++) tmp6[j] = tmp6[j]*tmp%P;
for(int j=0; j<(i<<1); j++) ret[j] = (tmp1[j]+tmp1[j]-tmp6[j]+P)%P;
}
} int main()
{
scanf("%d",&n); int dgr = 1; while(dgr<=n) dgr<<=1;
for(int i=0; i<n; i++) scanf("%lld",&a[i]);
polyinv(dgr,a,b);
for(int i=0; i<n; i++) printf("%lld ",b[i]);
return 0;
}

luogu P4238 多项式求逆 (模板题、FFT)的更多相关文章

  1. [模板][P4238]多项式求逆

    NTT多项式求逆模板,详见代码 #include <map> #include <set> #include <stack> #include <cmath& ...

  2. hdu 5730 Shell Necklace——多项式求逆+拆系数FFT

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5730 可以用分治FFT.但自己只写了多项式求逆. 和COGS2259几乎很像.设A(x),指数是长度,系数 ...

  3. 2018.12.30 洛谷P4238 【模板】多项式求逆

    传送门 多项式求逆模板题. 简单讲讲? 多项式求逆 定义: 对于一个多项式A(x)A(x)A(x),如果存在一个多项式B(x)B(x)B(x),满足B(x)B(x)B(x)的次数小于等于A(x)A(x ...

  4. 【BZOJ3625/CF438E】小朋友和二叉树(多项式求逆,多项式开方)

    [BZOJ3625/CF438E]小朋友和二叉树(多项式求逆,多项式开方) 题面 BZOJ CodeForces 大致题意: 对于每个数出现的次数对应的多项式\(A(x)\) 求\[f(x)=\fra ...

  5. 洛谷P4238【模板】多项式求逆

    洛谷P4238 多项式求逆:http://blog.miskcoo.com/2015/05/polynomial-inverse 注意:直接在点值表达下做$B(x) \equiv 2B'(x) - A ...

  6. luogu P4725 多项式对数函数 (模板题、FFT、多项式求逆、求导和积分)

    手动博客搬家: 本文发表于20181125 13:25:03, 原地址https://blog.csdn.net/suncongbo/article/details/84487306 题目链接: ht ...

  7. FFT模板 生成函数 原根 多项式求逆 多项式开根

    FFT #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> ...

  8. 洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)

    传送门 我是用多项式求逆做的因为分治FFT看不懂…… upd:分治FFT的看这里 话说这个万恶的生成函数到底是什么东西…… 我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x) ...

  9. 洛谷 P4721 [模板]分治FFT —— 分治FFT / 多项式求逆

    题目:https://www.luogu.org/problemnew/show/P4721 分治做法,考虑左边对右边的贡献即可: 注意最大用到的 a 的项也不过是 a[r-l] ,所以 NTT 可以 ...

随机推荐

  1. robin 今天来南大了

    今天非常高兴,在学校的体育馆见到了李彦宏博士. 这是第一次真实的见到了曾经仅仅能在媒体上才干够见到的人,真实,感觉非常好. 我算不上李彦宏的粉丝,也不是非常热衷于百度这个公司,可是我如今仍然心情澎湃. ...

  2. Linux vs Window

    目前国内Linux更多的是应用于服务器上,而桌面操作系统更多使用的是Window.主要区别如下: 比较 Windows Linux 界面 界面统一,外壳程序固定所有Windows程序菜单几乎一致,快捷 ...

  3. Android+Jquery Mobile学习系列(2)-HTML5/Jquery Mobile基础

    本章介绍两个关键字[HTML5]和[Jquery Mobile],简单说这两者的关系是:HTML5作为主体,Jquery Mobile在HTML5的基础上对其进行了优化.装饰. HTML5 HTML5 ...

  4. bzoj 4481 [ Jsoi 2015 ] 非诚勿扰 —— 期望

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4481 太弱了这种题都要看半天TJ...:https://blog.csdn.net/chai ...

  5. Java-JDK:JDK百科

    ylbtech-Java-JDK:JDK百科 JDK是 Java 语言的软件开发工具包,主要用于移动设备.嵌入式设备上的java应用程序.JDK是整个java开发的核心,它包含了JAVA的运行环境(J ...

  6. python使用MySQLdb向mySQL批量插入数据的方法

    该功能通过调用mySQLdb python库中的 cursor.executemany()函数完成批量处理. 今天用这个函数完成了批量插入 例程: def test_insertDB(options) ...

  7. XML案例(简单的考生成绩管理系统)

    1.以如下格式的exam.xml文件为例 <?xml version="1.0" encoding="UTF-8" standalone="no ...

  8. Python 33(1) UDP协议 数据报协议 socketsever模块

    一:基于UDP协议通信的套接字  基于UDP协议 只要是套接字,在开发的过程中一定要有服务端和客户端. UDP协议说的就是数据报协议,也就是说,基于UDP协议来发数据,每发一个数据,都是带有报头的数据 ...

  9. php 制作略缩图

    一.需求 最近公司的项目中有个需求,就是用户上传自己的微信二维码,然后系统会自动将用户的微信二维码合并到产品中 二.分析 因为该系统是手机端的,所以从用户端的体验出发,用户当然是直接在微信上保存二维码 ...

  10. 3Ddungeon-------三维搜索-----偷个懒 把 亡命逃窜 的代码修改了一下 拿来用了

    题 很简单  就是给一个   三维的迷宫然后 开你起始地点 S 问你能不能到达 出口 E 能的话 需要多长时间 ? #include<stdio.h> #include<string ...