| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 
 | #include<iostream>#include<cstdio>
 using namespace std;
 using ll=long long;
 ll qow(ll a,int b,int mod)
 {
 a%=mod;
 ll ans=1;
 while(b)
 {
 if(b&1) ans=ans*a%mod;
 a=a*a%mod;
 b>>=1;
 }
 return ans;
 }
 const ll mod1=998244353;
 const ll mod2=1004535809;
 const ll mod3=469762049;
 const ll inv1=qow(3,mod1-2,mod1);
 const ll inv2=qow(3,mod2-2,mod2);
 const ll inv3=qow(3,mod3-2,mod3);
 inline int read()
 {
 int s=0,w=1;char ch;
 while((ch=getchar())>'9'||ch<'0') if(ch=='-') w=-1;
 while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
 return s*w;
 }
 inline ll lread()
 {
 ll s=0,w=1;char ch;
 while((ch=getchar())>'9'||ch<'0') if(ch=='-') w=-1;
 while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
 return s*w;
 }
 int p;
 struct node
 {
 ll A,B,C;
 node(ll a,ll b,ll c){ A=a,B=b,C=c;}
 node(ll a=0){ A=B=C=a;}
 void operator = (int a){ A=a%mod1,B=a%mod2,C=a%mod3;}
 node operator + (node b){ return node((A+b.A)%mod1,(B+b.B)%mod2,(C+b.C)%mod3);}
 node operator - (node b){ return node((A+mod1-b.A)%mod1,(B+mod2-b.B)%mod2,(C+mod3-b.C)%mod3);}
 node operator * (node b){ return node(A*b.A%mod1,B*b.B%mod2,C*b.C%mod3);}
 ll get()
 {
 ll k1=(B-A+mod2)%mod2*qow(mod1,mod2-2,mod2)%mod2;
 ll x4=A+k1*mod1;
 ll k4=(C-x4%mod3+mod3)%mod3*qow(mod1*mod2,mod3-2,mod3)%mod3;
 return (k4%p*mod1%p*mod2%p+x4)%p;
 }
 }f[300001],g[300001];
 ostream & operator << (ostream &out,node a)
 {
 out<<'('<<a.A<<','<<a.B<<','<<a.C<<')';
 return out;
 }
 void swap(node &a,node &b){ node t=a;a=b,b=t;}
 int wh[300001];
 int a[300001];
 int b[300001];
 int n,m;
 void ntt(node *f,int dft)
 {
 for(int i=0;i<n;i++) if(i<wh[i]) swap(f[i],f[wh[i]]);
 for(int len=2;len<=n;len<<=1)
 {
 node step(qow(dft==1?3:inv1,(mod1-1)/len,mod1),qow(dft==1?3:inv2,(mod2-1)/len,mod2),qow(dft==1?3:inv3,(mod3-1)/len,mod3));
 int half=len>>1;
 for(int l=0;l<n;l+=len)
 {
 node now(1);
 for(int i=l;i<l+half;i++)
 {
 node num=now*f[i+half];
 f[i+half]=f[i]-num;
 f[i]=f[i]+num;
 now=now*step;
 }
 }
 }
 if(!dft)
 {
 ll num1=qow(n,mod1-2,mod1),num2=qow(n,mod2-2,mod2),num3=qow(n,mod3-2,mod3);
 node num(num1,num2,num3);
 for(int i=0;i<n;i++) f[i]=f[i]*num;
 }
 }
 void do_ntt(node *f,node *g)
 {
 for(int i=0;i<n;i++) wh[i]=(wh[i>>1]>>1)|((i&1)?n>>1:0);
 ntt(f,1),ntt(g,1);
 for(int i=0;i<n;i++) f[i]=f[i]*g[i];
 ntt(f,0);
 }
 int main()
 {
 n=read(),m=read(),p=read();
 for(int i=0;i<=n;i++) a[i]=read();
 for(int i=0;i<=m;i++) b[i]=read();
 for(m+=n,n=1;n<=m;n<<=1);
 for(int i=0;i<n;i++) f[i]=a[i],g[i]=b[i];
 do_ntt(f,g);
 for(int i=0;i<=m;i++) printf("%lld ",f[i].get());
 return 0;
 }
 
 |