日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多项式算法5:多项式求逆

發布時間:2023/12/31 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多项式算法5:多项式求逆 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

多項式算法5:多項式求逆

  • 多項式求逆

前置知識:
FFT
NTT

多項式求逆

這里的多項式求逆,其實是求多項式的逆元。
對于多項式A(x)A(x)A(x),如果存在A(x)B(x)≡1(modxn)A(x)B(x) \equiv 1( \mod x^n )A(x)B(x)1(modxn),那么我們稱B(x)B(x)B(x)A(x)A(x)A(x)在模xnx^nxn意義下的逆元。
這里的模xnx^nxn是指舍棄所有xxx的次數大于等于nnn的項,當然也可以理解為所有xxx的次數大于等于nnn的項的系數賦為零。
例如,多項式x4+4x3+6x2+4x+1x^4+4x^3+6x^2+4x+1x4+4x3+6x2+4x+1x3x^3x3取模后變為6x2+4x+16x^2+4x+16x2+4x+1
A(x)B(x)≡1(modxn)A(x)B(x) \equiv 1( \mod x^n )A(x)B(x)1(modxn),表示A(x)A(x)A(x)B(x)B(x)B(x)在模xnx^nxn的意義下相乘得到的多項式,只有常數項為111,其它項的系數均為000
小結論:如果滿足A(x)B(x)≡1(modxn)A(x)B(x) \equiv 1( \mod x^n )A(x)B(x)1(modxn),那么對于1≤m<n1 \le m \lt n1m<nA(x)B(x)≡1(modxm)A(x)B(x) \equiv 1( \mod x^m )A(x)B(x)1(modxm)也成立。
證明:不難發現由于A(x)B(x)≡1(modxn)A(x)B(x) \equiv 1( \mod x^n )A(x)B(x)1(modxn),表示A(x)B(x)A(x)B(x)A(x)B(x)的多項式的xxx111n?1n-1n?1次方項系數原本就均為000xxxnnn次方及更高次項已被強行賦了一個系數000。當模xm(1≤m<n)x^m(1 \le m \lt n)xm(1m<n)時,xxxmmmn?1n-1n?1次方項系數本來就為零,強行賦零后也不影響結果的正確性。
這相當于3%53 \% 53%53%63 \% 63%6結果一樣。
下面就是推導時間了。
我們設B(x)B(x)B(x)A(x)A(x)A(x)在模xnx^nxn意義下的逆元,B′(x)B'(x)B(x)A(x)A(x)A(x)在模x?n2?x^{\lceil \frac{n}{2} \rceil}x?2n??意義下的逆元,那么有:
A(x)?1≡B(x)(modxn)A(x)^{-1} \equiv B(x)( \mod x^n )A(x)?1B(x)(modxn)A(x)?1≡B′(x)(modx?n2?)A(x)^{-1} \equiv B'(x)( \mod x^{\lceil \frac{n}{2} \rceil} )A(x)?1B(x)(modx?2n??)B(x)≡B′(x)(modx?n2?)B(x) \equiv B'(x)( \mod x^{\lceil \frac{n}{2} \rceil} )B(x)B(x)(modx?2n??)B(x)?B′(x)≡0(modx?n2?)B(x) - B'(x) \equiv 0( \mod x^{\lceil \frac{n}{2} \rceil} )B(x)?B(x)0(modx?2n??)?n2??1\lceil \frac{n}{2} \rceil - 1?2n???1次項系數均為零,乘方后小于n?1n-1n?1次的項一定有一邊的系數來自前?n2??1\lceil \frac{n}{2} \rceil - 1?2n???1次項,系數也為000 (B(x)?B′(x))2≡0(modxn)(B(x) - B'(x))^2 \equiv 0( \mod x^{n} )(B(x)?B(x))20(modxn)B(x)2?2B(x)B′(x)+B′(x)2≡0(modxn)B(x)^2 - 2B(x)B'(x) + B'(x)^2 \equiv 0( \mod x^{n} )B(x)2?2B(x)B(x)+B(x)20(modxn)乘上A(x)A(x)A(x),有:A(x)B(x)B(x)?2A(x)B(x)B′(x)+A(x)B′(x)B′(x)≡0(modxn)A(x)B(x)B(x) - 2A(x)B(x)B'(x) + A(x)B'(x)B'(x) \equiv 0( \mod x^{n} )A(x)B(x)B(x)?2A(x)B(x)B(x)+A(x)B(x)B(x)0(modxn)因為A(x)B(x)≡1(modxn)A(x)B(x) \equiv 1( \mod x^n )A(x)B(x)1(modxn),所以有:B(x)?2B′(x)+A(x)B′(x)B′(x)≡0(modxn)B(x) - 2B'(x) + A(x)B'(x)B'(x) \equiv 0( \mod x^{n} )B(x)?2B(x)+A(x)B(x)B(x)0(modxn)B(x)≡2B′(x)?A(x)B′(x)B′(x)(modxn)B(x) \equiv 2B'(x) - A(x)B'(x)B'(x) ( \mod x^{n} )B(x)2B(x)?A(x)B(x)B(x)(modxn)B(x)≡B′(x)(2?A(x)B′(x))(modxn)B(x) \equiv B'(x)(2 - A(x)B'(x)) ( \mod x^{n} )B(x)B(x)(2?A(x)B(x))(modxn)
這說明,我們可以通過多項式乘法用B′(x)B'(x)B(x)求出B(x)B(x)B(x)n=1n=1n=1時直接求常數項逆元,倍增nnn,從小往大即可,時間復雜度為Θ(nlog?2n)\varTheta(n \log^2n)Θ(nlog2n)
我們的模板題還要求取模,模數998244353998244353998244353十分友好,故我們直接用NTT求解。
多項式求逆模板題

#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #define ll long long using namespace std; const int N = 1 << 22; const int g = 3 , gi = 332748118 , mod = 998244353; ll qw( ll a , ll b ) {ll ans = 1;while ( b ) {if( b & 1 ) {ans = ans * a % mod;}a = a * a % mod;b >>= 1;}return ans; } int rev[N]; int n; void pre( int bit ) {for ( int i = 0 ; i < ( 1 << bit ) ; ++i ) {rev[i] = (rev[i>>1]>>1)|((i&1)<<(bit - 1));} } void NTT( ll *F , int len , int on ) {for ( int i = 0 ; i < len ; ++i ) {if ( i < rev[i] ) {swap( F[i] , F[rev[i]] );}}for ( int i = 2 ; i <= len ; i <<= 1 ) {ll gn = qw( on ? g : gi , ( mod - 1 ) / ( i ) );for ( int j = 0 ; j <= len - 1 ; j += i ) {ll gg = 1;for ( int k = j ; k < j + i / 2 ; ++k ) {ll u = F[k];ll v = gg * F[k + i / 2] % mod;F[k] = (u + v) % mod;F[k + i / 2] = ( u - v + mod ) % mod;gg = gg * gn % mod;}}}return; } ll ta[N] , tb[N]; void solve( int len , ll *a , ll *b ) {if( len == 1 ) {b[0] = qw( a[0] , mod - 2 );return;}solve( ( len + 1 ) >> 1 , a , b );int l = 1;int bit = 0;while ( l <= len + n ) {l <<= 1;++bit;}pre( bit );for ( int i = 0 ; i < l ; ++i ) {ta[i] = a[i];tb[i] = ( i < ( ( len + 1 ) >> 1 ) ? b[i] : 0 );}NTT( ta , l , 1 );NTT( tb , l , 1 );for ( int i = 0 ; i < l ; ++i ) {ta[i] = tb[i] * ( ( ( 2 - ta[i] * tb[i] ) % mod + mod ) % mod ) % mod;}NTT( ta , l , 0 );ll inv = qw( l , mod - 2 );for ( int i = 0 ; i < len ; ++i ) {b[i] = ta[i] * inv % mod;} } ll a[N] , b[N]; int main(){scanf("%d",&n);for ( int i = 0 ; i < n ; ++i ) {scanf("%lld",&a[i]);}solve( n , a , b );for ( int i = 0 ; i < n ; ++i ) {printf("%lld ",b[i]);}return 0; }

總結

以上是生活随笔為你收集整理的多项式算法5:多项式求逆的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。