给定 A ( x ) A(x) A(x)求 B ( x ) = A − 1 ( x ) ( m o d x n ) B(x)=A^{-1}(x)(mod x^n) B(x)=A−1(x)(modxn)
使用倍增构造。
若n=1,则直接求0次项的乘法逆元。
若n>1
设 B ( x ) B(x) B(x)满足
A ( x ) B ( x ) ≡ 1 m o d    x n / 2 A(x)B(x)\equiv 1 \mod x^{n/2} A(x)B(x)≡1modxn/2
A ( x ) B ( x ) − 1 ≡ 0 m o d    x n / 2 A(x)B(x)-1\equiv 0 \mod x^{n/2} A(x)B(x)−1≡0modxn/2
( A ( x ) B ( x ) − 1 ) 2 ≡ 0 m o d    x n (A(x)B(x)-1)^2\equiv 0 \mod x^{n} (A(x)B(x)−1)2≡0modxn
A 2 ( x ) B 2 ( x ) − 2 A ( x ) B ( x ) + 1 ≡ 0 m o d    x n A^2(x)B^2(x)-2A(x)B(x)+1\equiv 0 \mod x^{n} A2(x)B2(x)−2A(x)B(x)+1≡0modxn
A ( x ) ( 2 B ( x ) − A ( x ) B 2 ( x ) ) ≡ 1 m o d    x n A(x)(2B(x)-A(x)B^2(x))\equiv 1 \mod x^{n} A(x)(2B(x)−A(x)B2(x))≡1modxn
2 B ( x ) − A ( x ) B 2 ( x ) ≡ A − 1 ( x ) m o d    x n 2B(x)-A(x)B^2(x)\equiv A^{-1}(x) \mod x^{n} 2B(x)−A(x)B2(x)≡A−1(x)modxn
递归即可,复杂度 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))
已知 A ( x ) , B ( x ) A(x),B(x) A(x),B(x),它们的次数分别为 n , m ( n > m ) n,m(n>m) n,m(n>m)
A ( x ) = B ( x ) C ( x ) + D ( x ) A(x)=B(x)C(x)+D(x) A(x)=B(x)C(x)+D(x)
求 C ( x ) C(x) C(x)是除法, D ( x ) D(x) D(x)是取模,其中 C ( x ) C(x) C(x)的系数不大于 n − m n-m n−m, D ( x ) D(x) D(x)的系数小于 m m m
首先可以发现 A ′ ( x ) = x n A ( 1 x ) A'(x)=x^nA({1\over x}) A′(x)=xnA(x1)就是将A的系数翻转过来。
同乘 x n x^n xn
那么
x n A ( 1 x ) = x m B ( 1 x ) x n − m C ( 1 x ) + x n − m + 1 x m − 1 D ( 1 x ) x^nA({1\over x})=x^mB({1\over x})x^{n-m}C({1\over x})+x^{n-m+1}x^{m-1}D({1\over x}) xnA(x1)=xmB(x1)xn−mC(x1)+xn−m+1xm−1D(x1)
将这个东西 m o d    x n − m + 1 \mod x^{n-m+1} modxn−m+1,可以发现对 C ( x ) C(x) C(x)的系数不会有影响。
于是
A ′ ( x ) ≡ B ′ ( x ) C ′ ( x ) m o d    x n − m + 1 A'(x)\equiv B'(x)C'(x) \mod x^{n-m+1} A′(x)≡B′(x)C′(x)modxn−m+1
C ′ ( x ) ≡ A ′ ( x ) B ′ − 1 ( x ) m o d    x n − m + 1 C'(x)\equiv A'(x)B'^{-1}(x) \mod x^{n-m+1} C′(x)≡A′(x)B′−1(x)modxn−m+1
于是多项式求逆,然后乘起来就没了。
A ( x ) = B ( x ) C ( x ) + D ( x ) A(x)=B(x)C(x)+D(x) A(x)=B(x)C(x)+D(x)
先除,再乘,再减,就没了。
给定 A ( x ) A(x) A(x)求 B 2 ( x ) = A ( x ) ( m o d x n ) B^2(x)=A(x)(mod x^n) B2(x)=A(x)(modxn)
使用倍增构造。
当n=1时,相当于求0次项的二次剩余。
(然而我并不会二次剩余,而且很多题里的常数项是真的常数,所以这里忽略二次剩余)
补一下二次剩余这个坑吧
我这辈子应该都学不会那个C开头的算法了。
但是可以BSGS对原根求出离散对数,把指数除个2,再幂回去。
对于二次剩余这个做法是正确的,如果指数是奇数不能除2,则这个数是没有二次剩余的。
(好像用后面的多项式求幂也能求这个)
当n>1时,
设 B ( x ) , G ( x ) B(x),G(x) B(x),G(x)满足
B 2 ( x ) ≡ A ( x ) m o d    x n / 2 , G 2 ( x ) ≡ A ( x ) m o d    x n B^2(x)\equiv A(x) \mod x^{n/2},G^2(x)\equiv A(x) \mod x^{n} B2(x)≡A(x)modxn/2,G2(x)≡A(x)modxn
G 2 ( x ) − B 2 ( x ) ≡ 0 m o d    x n / 2 G^2(x)-B^2(x)\equiv 0 \mod x^{n/2} G2(x)−B2(x)≡0modxn/2
两边平方
G 4 ( x ) + B 4 ( x ) − 2 G 2 ( x ) B 2 ( x ) ≡ 0 m o d    x n G^4(x)+B^4(x)-2G^2(x)B^2(x)\equiv 0 \mod x^{n} G4(x)+B4(x)−2G2(x)B2(x)≡0modxn
( G 2 ( x ) + B 2 ( x ) ) 2 ≡ 4 G 2 ( x ) B 2 ( x ) m o d    x n / 2 (G^2(x)+B^2(x))^2\equiv 4G^2(x)B^2(x) \mod x^{n/2} (G2(x)+B2(x))2≡4G2(x)B2(x)modxn/2
G 2 ( x ) + B 2 ( x ) ≡ 2 G ( x ) B ( x ) m o d    x n / 2 G^2(x)+B^2(x)\equiv 2G(x)B(x) \mod x^{n/2} G2(x)+B2(x)≡2G(x)B(x)modxn/2
因为 G 2 ( x ) ≡ A ( x ) m o d    x n G^2(x)\equiv A(x) \mod x^{n} G2(x)≡A(x)modxn
A ( x ) + B 2 ( x ) ≡ 2 G ( x ) B ( x ) m o d    x n / 2 A(x)+B^2(x)\equiv 2G(x)B(x) \mod x^{n/2} A(x)+B2(x)≡2G(x)B(x)modxn/2
A ( x ) 2 B ( x ) + B ( x ) 2 ≡ G ( x ) m o d    x n / 2 {A(x)\over 2B(x)}+{B(x)\over 2}\equiv G(x) \mod x^{n/2} 2B(x)A(x)+2B(x)≡G(x)modxn/2
求逆然后乘一乘,加一加就行了。
l n ( A ( x ) ) = ∫ [ l n ( A ( x ) ) ] ′ d x ln(A(x))=\int [ln(A(x))]'dx ln(A(x))=∫[ln(A(x))]′dx
= ∫ A ′ ( x ) A ( x ) d x =\int {A'(x)\over A(x)}dx =∫A(x)A′(x)dx
求导,求逆,然后积分即可。
有函数 g ( ) g() g(),解多项式 f f f的前n项使 g ( f ) = 0 g(f)=0 g(f)=0
f f f有2n项,设前n项使 f 0 f_0 f0
对 g ( f ) g(f) g(f)在 f 0 f_0 f0处泰勒展开
得
g ( f ) ≡ g ( f 0 ) + g ′ ( f 0 ) ( f − f 0 ) + g ′ ′ ( f 0 ) ( f − f 0 ) 2 2 ! + . . . m o d    x 2 n g(f)\equiv g(f_0)+g'(f_0)(f-f_0)+{g''(f0)(f-f_0)^2\over 2!}+... \mod x^{2n} g(f)≡g(f0)+g′(f0)(f−f0)+2!g′′(f0)(f−f0)2+...modx2n
注意到从第三项开始,在mod 2n意义下=0
所以
g ( f ) ≡ g ( f 0 ) + g ′ ( f 0 ) ( f − f 0 ) m o d    x 2 n g(f)\equiv g(f_0)+g'(f_0)(f-f_0) \mod x^{2n} g(f)≡g(f0)+g′(f0)(f−f0)modx2n
∵ g ( f ) = 0 \because g(f)=0 ∵g(f)=0
∴ g ( f 0 ) + g ′ ( f 0 ) ( f − f 0 ) ≡ 0 m o d    x 2 n \therefore g(f_0)+g'(f_0)(f-f_0)\equiv 0 \mod x^{2n} ∴g(f0)+g′(f0)(f−f0)≡0modx2n
f ≡ f 0 − g ( f 0 ) g ′ ( f 0 ) m o d    x 2 n f\equiv f_0-{g(f_0)\over g'(f_0)} \mod x^{2n} f≡f0−g′(f0)g(f0)modx2n
求 B ( x ) ≡ e x p ( A ( x ) ) m o d    x n B(x)\equiv exp(A(x)) \mod x^n B(x)≡exp(A(x))modxn
设 g ( x ) = l n ( x ) − A g(x)=ln(x)-A g(x)=ln(x)−A,那么目标是 g ( B ) = 0 g(B)=0 g(B)=0
B ≡ B 0 − g ( B 0 ) g ′ ( B 0 ) m o d    x n B\equiv B_0-{g(B_0)\over g'(B_0)}\mod x^n B≡B0−g′(B0)g(B0)modxn
∵ g ( B 0 ) ′ = 1 B 0 \because g(B_0)'={1\over B_0} ∵g(B0)′=B01
∴ B ≡ B 0 − B 0 ( l n ( B 0 ) − A ( x ) ) m o d    x n \therefore B\equiv B_0-B_0(ln(B_0)-A(x))\mod x^n ∴B≡B0−B0(ln(B0)−A(x))modxn
B ≡ B 0 ( 1 + A ( x ) − l n ( B 0 ) ) m o d    x n B\equiv B_0(1+A(x)-ln(B_0))\mod x^n B≡B0(1+A(x)−ln(B0))modxn
当n=1时直接求(程序中默认常数项=0)
当n>1时倍增
先ln,再乘上幂数,再exp。
这个代码对应的是bzoj3625 CF438E
#include
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define N 3201000
#define ll long long
#define mo 998244353
using namespace std;
int n,m;
ll len,a[N],b[N],c[N];
ll mi(ll a,ll b)
{
a%=mo;ll jy=1;
for(;b;b/=2,a=a*a%mo) if(b%2==1) jy=jy*a%mo;
return jy;
}
struct polynomial{
ll D[N],W[N],A[N],B[N],C[N],E[N],F[N];
void DFT(ll *a,int sig,int deg)
{
int len,lg;
for(len=1,lg=0;len<=deg;len*=2,lg++);
W[0]=1;W[1]=mi(3,(mo-1)/len);fo(i,2,len) W[i]=W[i-1]*W[1]%mo;
fo(i,0,len-1)
{
int p=0;
for(int j=0,tp=i;j