1. 程式人生 > >luogu P4512 多項式除法 (模板題、FFT、多項式求逆)

luogu P4512 多項式除法 (模板題、FFT、多項式求逆)

題目連結: https://www.luogu.org/problemnew/show/P4512

沒想到這演算法這麼蠢。。一點都不難啊。。我連這都推不出來我是不是沒救了

這個多項式滿足 A ( x ) = B (

x ) Q ( x ) + R ( x )
A(x)=B(x)Q(x)+R(x) , 如果已知 R ( x ) R(x) 0
0
, 那顯然很好處理,求個逆就行了。
那如果有餘數呢?很簡單,如果我們把這個多項式的係數翻轉(reverse),那麼 R ( x ) R(x) 就從低次項變成了高次項,低次項就不再受 R ( x ) R(x) 的而影響了。
這是我們的基本思路。下面我們來形式化這個過程:
A ( x ) = B ( x ) Q ( x ) + R ( x ) A(x)=B(x)Q(x)+R(x)
對於 n n 次多項式 F ( x ) F(x) F R ( x ) = x n F ( 1 x ) F_R(x)=x^nF(\frac{1}{x}) (這就是前面所說的reverse操作)
則有 x n A ( 1 x ) = x m B ( 1 x ) x n m Q ( 1 x ) + x m 1 R ( 1 x ) x n m + 1 x^nA(\frac{1}{x})=x^mB(\frac{1}{x})x^{n-m}Q(\frac{1}{x})+x^{m-1}R(\frac{1}{x})x^{n-m+1}
A R ( x ) = B R ( x ) Q R ( x ) + x n m + 1 R R ( x ) A_R(x)=B_R(x)Q_R(x)+x^{n-m+1}R_R(x)
A R ( x ) B R ( x ) Q R ( x ) ( m o d    x n m + 1 ) A_R(x)\equiv B_R(x)Q_R(x) (\mod x^{n-m+1})
於是我們求 B R ( x ) B_R(x) m o d    x n m + 1 \mod x^{n-m+1} 意義下的逆,然後乘以 A R ( x ) A_R(x) 即可求出 Q R ( x ) Q_R(x) , 從而得到 Q ( x ) Q(x) .
然後用 R ( x ) = A ( x ) B ( x ) Q ( x ) R(x)=A(x)-B(x)Q(x) 即可求出 R ( x ) R(x) .
(雖然演算法簡單但是要注意的地方還挺多……容易錯。)
時間複雜度 O ( n log n ) O(n\log n) , 我寫的進行了 24 24 倍常數的ntt.
空間複雜度 O ( n ) O(n) , 我的實現好像需要開 8 8 倍。

程式碼實現

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define llong long long
#define modinc(x) {if(x>=P) x-=P;}
using namespace std;

const int N = 1<<19;
const int LGN = 19;
const llong G = 3ll;
const int P = 998244353;
llong tmp1[N+3],tmp2[N+3],tmp3[N+3],tmp4[N+3];
llong tmp5[N+3],tmp6[N+3],tmp7[N+3],tmp8[N+3],tmp9[N+3];
llong a[N+3],b[N+3],q[N+3],r[N+3];
int id[N+3];
int n,m;

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)%P;}

void initid(int dgr)
{
 int len = 0; for(int i=0; i<=LGN; i++) if((1<<i)==dgr) {len = i; break;}
 id[0] = 0;
 for(int i=1; i<dgr; i++) id[i] = (id[i>>1]>>1)|(i&1)<<(len-1);
}

int getdgr(int x)
{
 int ret = 1;
 while(ret<=x) ret<<=1;
 return ret;
}

void ntt(int dgr,int coe,llong poly[],llong ret[])
{
 initid(dgr);
 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 = ret[j+i+k]*expn%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;
   }
  }
 }
 if(coe==-1)
 {
  llong tmp = mulinv(dgr);
  for(int j=0; j<dgr; j++) ret[j] = ret[j]*tmp%P;
 }
}

void polyinv(int dgr,llong poly[],llong ret[])
{
 for(int i=0; i<dgr; i++) ret[i] = 0ll;
 ret[0] = mulinv(poly
            
           

相關推薦

luogu P4512 多項式除法 (模板FFT多項式)

題目連結: https://www.luogu.org/problemnew/show/P4512 沒想到這演算法這麼蠢。。一點都不難啊。。我連這都推不出來我是不是沒救了 這個多項式滿足 A

luogu P4725 多項式對數函數 (模板FFT多項式導和積分)

lld sum %d detail define tdi 博客 while 復雜度 手動博客搬家: 本文發表於20181125 13:25:03, 原地址https://blog.csdn.net/suncongbo/article/details/84487306 題目鏈

海面模擬以及渲染(計算著色器FFTReflection Matrix)

GLfloat RandomUniform(const GLfloat start, const GLfloat end) { return ((GLfloat)rand() / (GLfloat)RAND_MAX) * (end - start) + start; } GLfloat RandomN

luogu P4238 多項式 (模板FFT)

pac namespace 有一個 計算 dft csdn include tmp eof 手動博客搬家: 本文發表於20181125 13:21:46, 原地址https://blog.csdn.net/suncongbo/article/details/84485718

洛谷 P4512 [模板] 多項式除法

題目:https://www.luogu.org/problemnew/show/P4512 看部落格:https://www.cnblogs.com/owenyu/p/6724611.html https://www.cnblogs.com/Mychael/p/9216906.html 注意取模那裡的

2019.01.02 洛谷P4512模板多項式除法

傳送門 解析 程式碼: #include<bits/stdc++.h> #define ri register int using namespace std; typedef long long ll; #define add(a,b) ((a)+(b)>=mod

P4512模板多項式除法

ons 兩個 fin cap 題解 tchar tmp ack res \(\color{#0066ff}{ 題目描述 }\) 給定一個 \(n\) 次多項式 \(F(x)\) 和一個 \(m\) 次多項式 \(G(x)\) ,請求出多項式 \(Q(x)\), \(R(x)

Luogu 2801 教主的魔法 | 分塊模板

錯誤 include pushd while 自己 single space using div Luogu 2801 教主的魔法 | 分塊模板題 我犯的錯誤: 有一處l打成了1,還看不出來…… 縮小塊大小De完bug後忘了把塊大小改回去就提交……還以為自己一定能A了……

多項式除法,開方,任意模數FFT

play 給定 得到 精度 markdown 分配 二次 splay 倒置 多項式求逆 給定\(A(x)\)求滿足\(A(x)*B(x)=1\)的\(B(x)\) 寫成 \[A(x)*B(x)=1(mod \ x^n)\] 我們會求\[A(x)*B(x)=1(mod \ x

Luogu 1494 - 小Z的襪子 - [莫隊算法模板]

query 每天 urn dot 相同 假設 == -o con 題目鏈接:https://www.luogu.org/problemnew/show/P1494 題目描述 作為一個生活散漫的人,小Z每天早上都要耗費很久從一堆五顏六色的襪子中找出一雙來穿。終於有一天,小Z再

HDU1402 FFT高精度乘法模板

#include<bits/stdc++.h> using namespace std; //HDU 1402 求高精度乘法 const double PI = acos(-1.0); //複數結構體 struct Complex { double x,y;//實部和虛

模板】分治FFT -cdq分治/多項式

傳送門:luogu【模板】分治 FFT 題意 給定長度為 n − 1

洛谷 4512 【模板多項式除法

題目:https://www.luogu.org/problemnew/show/P4512 學習:http://blog.miskcoo.com/2015/05/polynomial-division getinv裡最好弄一個臨時陣列存 a[ ] ,不要把 a ntt了。 #include<

洛谷 4721 【模板】分治 FFT——分治FFT / 多項式

題目:https://www.luogu.org/problemnew/show/P4721 分治FFT:https://www.cnblogs.com/bztMinamoto/p/9749557.html      https://blog.csdn.net/VictoryCzt/article/det

[多項式開根 模板] BZOJ 3625 [Codeforces Round #250]小朋友和二叉樹

令A(x)=∑i∈Sxi 以及f(x)為答案的母函式 那麼f(x)=A(x)∗f2(x)+1A(x)∗f2(x)−f(x)+1=0f(x)=1±1−4A(x)−−−−−−−−√2A(x)=21±1−4A(x)−−−−−−−−√ 因為f(0)=1 必取 21

[帶標號無向連通圖計數 容斥原理 多項式 多項式ln 模板] BZOJ 3456 城市規劃

可以通過容斥求出答案的表示式fi=2C2i−∑j=1i−1Cj−1i−1∗fj∗2C2i−j 其中前一部分表示i個點任意連邊 後半部分列舉1所在的連通塊然後容斥掉 ∑j=1ifj(j−1)!∗2C2i−j(i−j)!=2C2i(i−1)! 這是個卷積的

[多項式 模板] BZOJ 4555 [Tjoi2016&Heoi2016]求和

推導不多說了 在很久之前就寫過了 觀察柿子gn=∑i=1n2∗Cin∗gn−i 寫成卷積的形式 gnn!=∑i=1n2i!∗gn−i(n−i)! 那麼的話 分別令 f(x)=∑i=0∞gii

多項式模板【NTT/拆係數FFT

板題: 一. 洛谷4238: 模998244353,NTT: #include<cstdio> #include<algorithm> #define maxn 400005 #define LL long long using namesp

Luogu 4721 【模板】分治 FFT

還不會這題的多項式求逆的演算法。 發現每一項都是一個卷積的形式,那麼我們可以使用$NTT$來加速,直接做是$O(n^2logn)$的,我們考慮如何加速轉移。 可以採用$cdq$分治的思想,對於區間$[l, r]$中的數,先計算出$[l, mid]$中的數對$[mid + 1, r]$中的數的貢獻,然後直接

Java大數模板——加法減法乘法除法開方

1、BigInteger的運算 import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(String[] args) { //