多项式模板
模板错的次数太多了,甚至模板题错了都能过。/zk/zk/zk 记录一下
多项式乘法
void ntt ( int *a , int lm ) {
for ( int i = 1 ; i < lm ; ++ i )
if ( i < tx [ i ] )
swap ( a [ i ] , a [ tx [ i ] ] ) ;
for ( int i = 1 ; i < lm ; i <<= 1 ) {
int x = qpow ( G , ( M - 1 ) / ( i << 1 ) ) ;
for ( int j = 0 ; j < lm ; j += ( i << 1 ) ) {
for ( int k = 0 , y = 1 ; k < i ; ++ k , y = y * x % M ) {
int p = a [ j + k ] , q = y * a [ j + k + i ] % M ;
a [ j + k ] = Ct ( p + q ) ;
a [ j + k + i ] = Cs ( p - q ) ;
}
}
}
}
分治多项式乘法
#include <iostream>
#include <algorithm>
using namespace std ;
#define int long long
inline int read ( ) {
char ch = getchar ( ) ;
int x = 0 ;
while ( ch < '0' || ch > '9' )
ch = getchar ( ) ;
while ( ch >= '0' && ch <= '9' )
x = x * 10 + ch - 48 , ch = getchar ( ) ;
return x ;
}
const int N = (1<<18) + 5 , M = 998244353 , G = 3 ;
int n , lim , f[N] , g[N] , u[N] , v[N] , tx[N] , lg[N] ;
inline int qpow ( int x , int y ) {
int res = 1 ;
while ( y ) {
if ( y & 1 )
res = res * x % M ;
x = x * x % M ;
y >>= 1 ;
}
return res ;
}
int Ct ( int x ) { return x >= M ? x - M : x ; }
int Cs ( int x ) { return x < 0 ? x + M : x ; }
void ntt ( int *a , int lm ) {
for ( int i = 1 ; i < lm ; ++ i )
if ( i < tx [ i ] )
swap ( a [ i ] , a [ tx [ i ] ] ) ;
for ( int i = 1 ; i < lm ; i <<= 1 ) {
int x = qpow ( G , ( M - 1 ) / ( i << 1 ) ) ;
for ( int j = 0 ; j < lm ; j += ( i << 1 ) ) {
for ( int k = 0 , y = 1 ; k < i ; ++ k , y = y * x % M ) {
int p = a [ j + k ] , q = y * a [ j + k + i ] % M ;
a [ j + k ] = Ct ( p + q ) ;
a [ j + k + i ] = Cs ( p - q ) ;
}
}
}
}
void solve ( int l , int r ) {
if ( l == r ) {
if ( l == 0 ) f [ l ] = 1 ;
return ;
}
int mid = ( l + r ) >> 1 ;
solve ( l , mid ) ;
int lim = r - l + 1 ;
for ( int i = l ; i <= r ; ++ i )
u [ i - l ] = f [ i ] , v [ i - l ] = g [ i - l ] ;
for ( int i = ( lim >> 1 ) ; i < lim ; ++ i )
u [ i ] = 0 ;
for ( int i = lim ; i < ( lim << 1 ) ; ++ i )
u [ i ] = v [ i ] = 0 ;
lim <<= 1 ;
int len = lg [ r - l + 1 ] ;
for ( int i = 1 ; i < lim ; ++ i )
tx [ i ] = ( tx [ i >> 1 ] >> 1 ) | ( ( i & 1 ) << len ) ;
ntt ( u , lim ) , ntt ( v , lim ) ;
for ( int i = 0 ; i < lim ; ++ i )
u [ i ] = u [ i ] * v [ i ] % M ;
ntt ( u , lim ) ;
reverse ( u + 1 , u + lim ) ;
int lv = qpow ( lim , M - 2 ) ;
lim >>= 1 ;
for ( int i = ( lim >> 1 ) ; i < lim ; ++ i )
f [ l + i ] = Ct ( f [ l + i ] + u [ i ] * lv % M ) ;
solve ( mid + 1 , r ) ;
}
signed main ( ) {
n = read ( ) ;
for ( int i = 1 ; i < n ; ++ i )
g [ i ] = read ( ) ;
lim = 1 ;
while ( lim < n ) lim <<= 1 ;
lg [ 0 ] = -1 ;
for ( int i = 1 ; i <= lim ; ++ i )
lg [ i ] = lg [ i >> 1 ] + 1 ;
solve ( 0 , lim - 1 ) ;
for ( int i = 0 ; i < n ; ++ i )
cout << f [ i ] << " " ;
cout << "\n" ;
return 0 ;
}
多项式求逆
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std ;
#define int long long
const int N = 400005 , M = 998244353 , G = 3 ;
inline int read ( ) {
char ch = getchar ( ) ;
int x = 0 ;
while ( ch < '0' || ch > '9' )
ch = getchar ( ) ;
while ( ch >= '0' && ch <= '9' )
x = x * 10 + ch - 48 , ch = getchar ( ) ;
return x ;
}
inline int qpow ( int x , int y ) {
int res = 1 ;
while ( y ) {
if ( y & 1 )
res = res * x % M ;
x = x * x % M ;
y >>= 1 ;
}
return res ;
}
inline int Ct ( int x ) { return x >= M ? x - M : x ; }
inline int Cs ( int x ) { return x < 0 ? x + M : x ; }
int n , tx[N] , a[N] , b[N] ;
void ntt ( int *a , int lm ) {
for ( int i = 1 ; i < lm ; ++ i )
if ( i < tx [ i ] )
swap ( a [ i ] , a [ tx [ i ] ] ) ;
for ( int i = 1 ; i < lm ; i <<= 1 ) {
int x = qpow ( G , ( M - 1 ) / ( i << 1 ) ) ;
for ( int j = 0 ; j < lm ; j += ( i << 1 ) ) {
for ( int k = 0 , y = 1 ; k < i ; ++ k , y = y * x % M ) {
int p = a [ j + k ] , q = y * a [ j + k + i ] % M ;
a [ j + k ] = Ct ( p + q ) ;
a [ j + k + i ] = Cs ( p - q ) ;
}
}
}
}
void Inv ( int *a , int *b , int n ) {
static int c[N] ;
memset ( c , 0 , sizeof ( c ) ) ;
b [ 0 ] = qpow ( a [ 0 ] , M - 2 ) ;
int len , lm ;
for ( len = 2 ; len <= n ; len <<= 1 ) {
lm = len << 1 ;
for ( int i = 0 ; i < len ; ++ i )
c [ i ] = a [ i ] ;
for ( int i = 1 ; i < lm ; ++ i )
tx [ i ] = ( tx [ i >> 1 ] >> 1 ) | ( ( i & 1 ) ? len : 0 ) ;
ntt ( c , lm ) , ntt ( b , lm ) ;
for ( int i = 0 ; i < lm ; ++ i )
b [ i ] = Cs ( 2 - b [ i ] * c [ i ] % M ) * b [ i ] % M ;
ntt ( b , lm ) ;
reverse ( b + 1 , b + lm ) ;
int lv = qpow ( lm , M - 2 ) ;
for ( int i = 0 ; i < len ; ++ i )
b [ i ] = b [ i ] * lv % M ;
for ( int i = len ; i < lm ; ++ i )
b [ i ] = 0 ;
}
for ( int i = n ; i < len ; ++ i )
b [ i ] = 0 ;
}
signed main ( ) {
n = read ( ) ;
for ( int i = 0 ; i < n ; ++ i )
a [ i ] = read ( ) ;
int lim = 1 ;
while ( lim <= n ) lim <<= 1 ;
Inv ( a , b , lim ) ;
for ( int i = 0 ; i < n ; ++ i )
cout << b [ i ] << " " ;
cout << "\n" ;
return 0 ;
}
多项式Ln
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std ;
#define int long long
const int N = 400005 , M = 998244353 , G = 3 ;
inline int read ( ) {
char ch = getchar ( ) ;
int x = 0 ;
while ( ch < '0' || ch > '9' )
ch = getchar ( ) ;
while ( ch >= '0' && ch <= '9' )
x = x * 10 + ch - 48 , ch = getchar ( ) ;
return x ;
}
inline int qpow ( int x , int y ) {
int res = 1 ;
while ( y ) {
if ( y & 1 )
res = res * x % M ;
x = x * x % M ;
y >>= 1 ;
}
return res ;
}
inline int Ct ( int x ) { return x >= M ? x - M : x ; }
inline int Cs ( int x ) { return x < 0 ? x + M : x ; }
int n , tx[N] , a[N] , b[N] , A[N] ;
void ntt ( int *a , int lm ) {
for ( int i = 1 ; i < lm ; ++ i )
if ( i < tx [ i ] )
swap ( a [ i ] , a [ tx [ i ] ] ) ;
for ( int i = 1 ; i < lm ; i <<= 1 ) {
int x = qpow ( G , ( M - 1 ) / ( i << 1 ) ) ;
for ( int j = 0 ; j < lm ; j += ( i << 1 ) ) {
for ( int k = 0 , y = 1 ; k < i ; ++ k , y = y * x % M ) {
int p = a [ j + k ] , q = y * a [ j + k + i ] % M ;
a [ j + k ] = Ct ( p + q ) ;
a [ j + k + i ] = Cs ( p - q ) ;
}
}
}
}
void Inv ( int *a , int *b , int n ) {
static int c[N] ;
memset ( c , 0 , sizeof ( c ) ) ;
b [ 0 ] = qpow ( a [ 0 ] , M - 2 ) ;
int len , lm ;
for ( len = 2 ; len <= n ; len <<= 1 ) {
lm = len << 1 ;
for ( int i = 0 ; i < len ; ++ i )
c [ i ] = a [ i ] ;
for ( int i = 1 ; i < lm ; ++ i )
tx [ i ] = ( tx [ i >> 1 ] >> 1 ) | ( ( i & 1 ) ? len : 0 ) ;
ntt ( c , lm ) , ntt ( b , lm ) ;
for ( int i = 0 ; i < lm ; ++ i )
b [ i ] = Cs ( 2 - b [ i ] * c [ i ] % M ) * b [ i ] % M ;
ntt ( b , lm ) ;
reverse ( b + 1 , b + lm ) ;
int lv = qpow ( lm , M - 2 ) ;
for ( int i = 0 ; i < len ; ++ i )
b [ i ] = b [ i ] * lv % M ;
for ( int i = len ; i < lm ; ++ i )
b [ i ] = 0 ;
}
for ( int i = n ; i < len ; ++ i )
b [ i ] = 0 ;
}
void Deri ( int *a , int lm ) {
for ( int i = 0 ; i < lm - 1 ; ++ i )
a [ i ] = a [ i + 1 ] * ( i + 1 ) % M ;
a [ lm - 1 ] = 0 ;
}
void Inte ( int *a , int lm ) {
for ( int i = lm - 1 ; i > 0 ; -- i )
a [ i ] = a [ i - 1 ] * qpow ( i , M - 2 ) % M ;
a [ 0 ] = 0 ;
}
signed main ( ) {
n = read ( ) ;
for ( int i = 0 ; i < n ; ++ i )
b [ i ] = A [ i ] = read ( ) ;
int len = 1 ;
while ( len <= n ) len <<= 1 ;
int lm = len << 1 ;
Deri ( b , len ) ;
Inv ( A , a , len ) ;
for ( int i = 1 ; i < lm ; ++ i )
tx [ i ] = ( tx [ i >> 1 ] >> 1 ) | ( ( i & 1 ) ? len : 0 ) ;
ntt ( a , lm ) , ntt ( b , lm ) ;
for ( int i = 0 ; i < lm ; ++ i )
a [ i ] = a [ i ] * b [ i ] % M ;
ntt ( a , lm ) ;
reverse ( a + 1 , a + lm ) ;
int lv = qpow ( lm , M - 2 ) ;
for ( int i = 0 ; i < lm ; ++ i )
a [ i ] = a [ i ] * lv % M ;
Inte ( a , lm ) ;
for ( int i = 0 ; i < n ; ++ i )
cout << a [ i ] << " " ;
cout << "\n" ;
return 0 ;
}
多项式Exp
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std ;
#define int long long
const int N = 400005 , M = 998244353 , G = 3 ;
inline int read ( ) {
char ch = getchar ( ) ;
int x = 0 ;
while ( ch < '0' || ch > '9' )
ch = getchar ( ) ;
while ( ch >= '0' && ch <= '9' )
x = x * 10 + ch - 48 , ch = getchar ( ) ;
return x ;
}
inline int qpow ( int x , int y ) {
int res = 1 ;
while ( y ) {
if ( y & 1 )
res = res * x % M ;
x = x * x % M ;
y >>= 1 ;
}
return res ;
}
inline int Ct ( int x ) { return x >= M ? x - M : x ; }
inline int Cs ( int x ) { return x < 0 ? x + M : x ; }
int n , tx[N] , a[N] , b[N] ;
void ntt ( int *a , int lm ) {
for ( int i = 1 ; i < lm ; ++ i )
if ( i < tx [ i ] )
swap ( a [ i ] , a [ tx [ i ] ] ) ;
for ( int i = 1 ; i < lm ; i <<= 1 ) {
int x = qpow ( G , ( M - 1 ) / ( i << 1 ) ) ;
for ( int j = 0 ; j < lm ; j += ( i << 1 ) ) {
for ( int k = 0 , y = 1 ; k < i ; ++ k , y = y * x % M ) {
int p = a [ j + k ] , q = y * a [ j + k + i ] % M ;
a [ j + k ] = Ct ( p + q ) ;
a [ j + k + i ] = Cs ( p - q ) ;
}
}
}
}
void Inv ( int *a , int *b , int n ) {
static int c[N] ;
memset ( c , 0 , sizeof ( c ) ) ;
b [ 0 ] = qpow ( a [ 0 ] , M - 2 ) ;
int len , lm ;
for ( len = 2 ; len <= n ; len <<= 1 ) {
lm = len << 1 ;
for ( int i = 0 ; i < len ; ++ i )
c [ i ] = a [ i ] ;
for ( int i = 1 ; i < lm ; ++ i )
tx [ i ] = ( tx [ i >> 1 ] >> 1 ) | ( ( i & 1 ) ? len : 0 ) ;
ntt ( c , lm ) , ntt ( b , lm ) ;
for ( int i = 0 ; i < lm ; ++ i )
b [ i ] = Cs ( 2 - b [ i ] * c [ i ] % M ) * b [ i ] % M ;
ntt ( b , lm ) ;
reverse ( b + 1 , b + lm ) ;
int lv = qpow ( lm , M - 2 ) ;
for ( int i = 0 ; i < len ; ++ i )
b [ i ] = b [ i ] * lv % M ;
for ( int i = len ; i < lm ; ++ i )
b [ i ] = 0 ;
}
for ( int i = n ; i < len ; ++ i )
b [ i ] = 0 ;
}
void Deci ( int *a , int lm ) {
for ( int i = 0 ; i < lm - 1 ; ++ i )
a [ i ] = a [ i + 1 ] * ( i + 1 ) % M ;
a [ lm - 1 ] = 0 ;
}
void Inte ( int *a , int lm ) {
for ( int i = lm - 1 ; i ; -- i )
a [ i ] = a [ i - 1 ] * qpow ( i , M - 2 ) % M ;
a [ 0 ] = 0 ;
}
void Ln ( int *a , int *b , int n ) {
static int c[N] ;
memset ( c , 0 , sizeof ( c ) ) ;
for ( int i = 0 ; i < n ; ++ i )
c [ i ] = a [ i ] ;
Deci ( c , n ) ;
Inv ( a , b , n ) ;
int lm = n << 1 ;
for ( int i = 1 ; i < lm ; ++ i )
tx [ i ] = ( tx [ i >> 1 ] >> 1 ) | ( ( i & 1 ) ? n : 0 ) ;
ntt ( c , lm ) , ntt ( b , lm ) ;
for ( int i = 0 ; i < lm ; ++ i )
b [ i ] = c [ i ] * b [ i ] % M ;
ntt ( b , lm ) ;
reverse ( b + 1 , b + lm ) ;
int lv = qpow ( lm , M - 2 ) ;
for ( int i = 0 ; i < lm ; ++ i )
b [ i ] = b [ i ] * lv % M ;
Inte ( b , lm ) ;
for ( int i = n ; i < lm ; ++ i )
b [ i ] = 0 ;
}
void Exp ( int *a , int *b , int n ) {
static int c[N] ;
b [ 0 ] = 1 ;
int len , lm ;
for ( len = 2 ; len <= n ; len <<= 1 ) {
lm = len << 1 ;
memset ( c , 0 , sizeof ( c ) ) ;
Ln ( b , c , len ) ;
for ( int i = 0 ; i < len ; ++ i )
c [ i ] = Cs ( a [ i ] - c [ i ] ) ;
c [ 0 ] = Ct ( c [ 0 ] + 1 ) ;
for ( int i = 1 ; i < lm ; ++ i )
tx [ i ] = ( tx [ i >> 1 ] >> 1 ) | ( ( i & 1 ) ? len : 0 ) ;
ntt ( c , lm ) , ntt ( b , lm ) ;
for ( int i = 0 ; i < lm ; ++ i )
b [ i ] = c [ i ] * b [ i ] % M;
ntt ( b , lm ) ;
reverse ( b + 1 , b + lm ) ;
int lv = qpow ( lm , M - 2 ) ;
for ( int i = 0 ; i < len ; ++ i )
b [ i ] = b [ i ] * lv % M ;
for ( int i = len ; i < lm ; ++ i )
b [ i ] = 0 ;
}
for ( int i = n ; i < len ; ++ i )
b [ i ] = 0 ;
}
signed main ( ) {
n = read ( ) ;
for ( int i = 0 ; i < n ; ++ i )
a [ i ] = read ( ) ;
int lm = 1 ;
while ( lm <= n ) lm <<= 1 ;
Exp ( a , b , lm ) ;
for ( int i = 0 ; i < n ; ++ i )
cout << b [ i ] << " " ;
cout << "\n" ;
return 0 ;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】