polynomial fast power
Time limit: 60000 MS space limit: 524288 KB
Problem Description:
Give an n-th polynomial, ask for it's K-th square. It doesn't matter, just die a 998244353 on the line. It doesn't matter, it's OK to model an XM.
Input format:
The first row n, meaning as above.
The second row n+1 number, a0,a1,..., an, respectively, is 0,1,..., n times coefficient.
The third row K, meaning as above.
The Forth line m, meaning as above.
Output format
One line, B0,b1,..., bm-1, respectively, is 0,1,..., m-1 sub-coefficient.
Sample input
1
1 1
5
2
Sample output
1 5
Tips
Sample explanation:
(1+X) 5
=1+5x+10x2+10x3+5x4+x5
≡1+5x (mod x2)
Data range:
n,m<=100000
k<=1018
Newton iterations are used when seeking inverse and exp.
#include <iostream> #include <cstdio> #include <algorithm> #include <cstdlib> #include <
Cstring> #include <complex> #define LL long long using namespace std;
Template <typename t> inline void _read (t& x) {char t=getchar (); bool sign=true; while (t< ' 0 ' | |
T> ' 9 ') {if (t== '-') Sign=false;t=getchar ();}
for (x=0;t>= ' 0 ' &&t<= ' 9 '; T=getchar ()) x=x*10+t-' 0 ';
if (!sign) x=-x;
} const int p=998244353;
const int g=3;
int mont (int x,int y) {ll ans=1;
for (x%=p;y;y>>=1,x=1ll*x*x%p) {if (y&1) ans=1ll*ans*x%p;
} return int (ANS);
} int fft_wi[300005];
void FFT (int a[],int n,int ty) {int i,j,k,m,t0,t1; for (i=0;i<n;i++) {for (j=0,k=i,m=1;m<n;m<<=1,j= (j<<1) | (
k&1), k>>=1);
if (i<j) swap (a[i],a[j]);
} fft_wi[0]=1;
for (m=1;m<n;m<<=1) {T0=mont (g,p-1+ty* (p-1)/(m<<1)); for (i=1;i<m;i++) Fft_wi[i]=1ll*fft_wi[i-1]*t0%p;
For (k=0;k<n;k+= (m<<1)) {for (i=k;i<k+m;i++) {t0=a[i];
t1=1ll*a[i+m]*fft_wi[i-k]%p;
A[i]=t0+t1;if (a[i]>=p) a[i]-=p;
A[i+m]=t0-t1;if (a[i+m]<0) a[i+m]+=p;
}}} if (Ty==1) return;
T0=mont (n,p-2);
for (i=0;i<n;i++) {a[i]=1ll*a[i]*t0%p;
}} int d[300005],e[300005];
void multi (int a[],int b[],int c[],int la,int lb) {int i,j,k,t,n;
Memset (d,0,sizeof (d));
memset (E,0,sizeof (e));
for (i=0;i<la;i++) d[i]=a[i];
for (i=0;i<lb;i++) e[i]=b[i];
N=1;
while (n<= (la+lb+1)) n<<=1;
FFT (d,n,1);
FFT (e,n,1);
for (i=0;i<n;i++) d[i]=1ll*d[i]*e[i]%p;
FFT (d,n,-1);
for (i=0;i<la+lb-1;i++) c[i]=d[i];
for (i=la+lb-1;i<n;i++) c[i]=0;
} int inv_c[300005];
void Inv (int a[],int b[],int la,int lb) {memset (inv_c,0,sizeof (Inv_c));
int i,j,k,t,n,m;
B[0]=mont (a[0],p-2); FoR (m=1;m<lb;m<<=1) {n=m<<1;
for (i=0;i<n;i++) inv_c[i]=a[i];
for (n<<=1;i<n;i++) inv_c[i]=0;
for (i=m;i<n;i++) b[i]=0;
FFT (inv_c,n,1);
FFT (b,n,1);
for (i=0;i<n;i++) inv_c[i]=p+2-1ll*inv_c[i]*b[i]%p;
for (i=0;i<n;i++) inv_c[i]= (inv_c[i]%p+p)%p;
for (i=0;i<n;i++) b[i]=1ll*b[i]*inv_c[i]%p;
FFT (b,n,-1);
} for (i=lb;i<n;i++) b[i]=0;
} int ln_c[300005],ln_d[300005],ln_e[300005];
void ln (int a[],int b[],int la,int lb) {int i,j,k,t,n;
N=1; while (n<la| |
N<LB) n<<=1;
memset (ln_c,0,sizeof (Ln_c));
memset (ln_d,0,sizeof (Ln_d));
memset (ln_e,0,sizeof (ln_e));
for (i=0;i<la;i++) ln_c[i]=a[i];
INV (ln_c,ln_d,la,n);
for (i=1;i<la;i++) ln_c[i-1]=1ll*a[i]*i%p;
for (i=la-1;i<n;i++) ln_c[i]=0;
multi (ln_d,ln_c,ln_e,n,la-1);
for (i=2,ln_c[1]=1;i<lb;i++) ln_c[i]=1ll* (p-p/i) *ln_c[p%i]%p; for (i=1;i<lb;i++) b[i]=1ll*ln_e[i-1]*ln_c[i]%P
b[0]=0;
for (i=lb;i<n;i++) b[i]=0;
} int exp_c[300005],exp_d[300005];
void exp (int a[],int b[],int la,int lb) {int i,j,k,t,n,m;
for (m=1;m<lb;m<<=1) {n= (m<<1);
ln (b,exp_c,m,n);
Exp_d[0]=1;
for (i=1;i<n;i++) exp_d[i]=0;
for (i=0;i<n;i++) exp_d[i]+=a[i];
for (i=0;i<n;i++) if (exp_d[i]>=p) exp_d[i]-=p;
for (i=0;i<n;i++) exp_d[i]-=exp_c[i];
for (i=0;i<n;i++) if (exp_d[i]<0) exp_d[i]+=p;
multi (b,exp_d,exp_c,m,n);
for (i=0;i<n;i++) b[i]=exp_c[i];
}} int poly_d[300005],poly_e[300005];
void Poly_mont (int a[],int c[],ll num,int la,int LC) {int i,j,k,t,n,ld,le;
ln (A,POLY_D,LA,LC);
t=num%p;
for (i=0;i<lc;i++) poly_d[i]=1ll*poly_d[i]*t%p;
C[0]=mont (a[0],num% (p-1));
exp (POLY_D,C,LC,LC);
} int a[300005],b[300005];
int main () {int i,j,la,lb;
ll K;
cin>>la;la++;
for (i=0;i<la;i++) {_read (a[i]); } cin>>k>>lb;
Poly_mont (A,B,K,LA,LB);
for (i=0;i<lb;i++) {printf ("%d", b[i]); }
}