关于多项式的操作,我会慢慢补充的。
多项式求ln
- 前置公式,
和
。
- 前置知识,多项式点值表示,多项式求逆。
给你一个多项式 ,要求求出一个多项式满足
。考虑积分和求导。我们考虑
是
和
复合。那么
那么
,左右同时积分
。那么就做完了。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 4e6 + 100,P = 998244353;
int limit,r[N],L;
int ksm(int a,int b) {int x=1;for(;b;b>>=1,a=1LL*a*a%P)if(b&1)x=1LL*x*a%P;return x;}
void NTT(int *a,int type) {
for(int i=0;i<limit;i++)if(i>r[i])swap(a[i],a[r[i]]);
for(int mid=1;mid<limit;mid<<=1) {
int wn=ksm(3,(P-1)/(mid<<1));for(int i=0;i<limit;i+=(mid<<1)){
for(int j=0,w=1;j<mid;j++,w=1LL*w*wn%P) {
int x=a[i+j],y=1LL*a[i+j+mid]*w%P;
a[i+j]=(x+y)%P;a[i+j+mid]=(x-y+P)%P;
}
}
}
if(type==-1) {reverse(a+1,a+limit);int Inv=ksm(limit,P-2);for(int i=0;i<limit;i++)a[i]=1LL*a[i]*Inv%P;}
}
void Mul(int *f,int *g,int len) {
static int G[N];
memcpy(G,g,sizeof(G));
NTT(f,1);NTT(g,1);
for(int i = 0;i < limit;i++) f[i] = 1LL * f[i] * g[i] % P;
NTT(f,-1);for(int i=len+1;i<limit;i++) f[i]=0;
}
void init(int len) {
limit=1;L=0;while(limit<=len)limit<<=1,L++;
for(int i=0;i<limit;i++)r[i]=(r[i>>1]>>1)|((i&1)<<L-1);
}
void GetInv(int *f,int *g,int n) {
if(n==1) {g[0]=ksm(f[0],P-2);return;}
GetInv(f,g,(n+1)>>1);
init(n+n-2);
static int c[N];memset(c,0,sizeof(c));
for(int i = 0;i < n;i++) c[i] = f[i];
NTT(c,1);NTT(g,1);
for(int i = 0;i < limit;i++) g[i] = 1LL * g[i] * ((2LL - 1LL * c[i] * g[i] % P + P) % P) % P;
NTT(g,-1);for(int i = n;i < limit;i++) g[i] = 0;
}
void Dao(int *f,int *g,int n) {
for(int i = 1;i < n;i++) g[i-1]=1LL*f[i]*i%P;g[n-1]=0;
}
void JiFen(int *f,int *g,int n) {
for(int i = 1;i < n;i++) g[i]=1LL*f[i-1]*ksm(i,P-2)%P;g[0]=0;
}
void GetLn(int *f,int *g,int n) {
static int A[N],B[N];memset(A,0,sizeof(A));memset(B,0,sizeof(B));
Dao(f,A,n);GetInv(f,B,n);
init(n+n-2);NTT(A,1);NTT(B,1);
for(int i=0;i<limit;i++)A[i]=1LL*A[i]*B[i]%P;
NTT(A,-1);JiFen(A,g,n);
}
int f[N],g[N];
int main() {
int n;
cin >> n;for(int i = 0;i < n;i++) cin >> f[i];
GetLn(f,g,n);
for(int i = 0;i < n;i++) cout << g[i] << " ";
return 0;
}
京公网安备 11010502036488号