luogu4389(多项式指数函数)

题目链接

https://www.luogu.org/problem/P4389

题解

用多项式表示就是

然后直接按值分类暴力求解指数即可,然后上多项式指数函数




代码

1
2
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
*         ┏┓    ┏┓
*         ┏┛┗━━━━━━━┛┗━━━┓
*         ┃       ┃  
*         ┃   ━    ┃
*         ┃ >   < ┃
*         ┃       ┃
*         ┃... ⌒ ...  ┃
*         ┃ ┃
*         ┗━┓ ┏━┛
*          ┃ ┃ Code is far away from bug with the animal protecting          
*          ┃ ┃ 神兽保佑,代码无bug
*          ┃ ┃           
*          ┃ ┃       
*          ┃ ┃
*          ┃ ┃           
*          ┃ ┗━━━┓
*          ┃ ┣┓
*          ┃ ┏┛
*          ┗┓┓┏━━━━━━━━┳┓┏┛
*           ┃┫┫ ┃┫┫
*           ┗┻┛ ┗┻┛
*/

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<set>
#include<bitset>
#include<complex>
#include<cstdlib>
#include<assert.h>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-8
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define mid (x+y>>1)
#define sqr(x) ((x)*(x))
#define NM 300000
#define nm 2097152
using namespace std;
const double pi=acos(-1);
const ll inf=998244353;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}


inline void reduce(ll&x){x+=x>>63&inf;}
inline ll qpow(ll x,ll t){
ll s=1;
for(;t;t>>=1,x=x*x%inf)if(t&1)s=s*x%inf;
return s;
}
int n,m;
ll a[NM],b[NM],inv[NM];
int v[NM];


namespace Poly{
int lim,bit,rev[NM],w[NM],W[NM];
ll invn;
inline void clear(ll*a,ll*b){if(a<b)memset(a,0,sizeof(ll)*(b-a));}
void init(int m){
for(lim=1,bit=0;lim<m;lim<<=1)bit++;invn=qpow(lim,inf-2);
inc(i,1,lim-1)rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
ll t=qpow(3,(inf-1)/lim);W[0]=1;
inc(i,1,lim)W[i]=W[i-1]*t%inf;
}
void fft(ll*a,int f=0){
int n=lim;
inc(i,1,n-1)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int k=1;k<n;k<<=1){
int t=n/k>>1;
for(int i=0,j=0;i<k;i++,j+=t)w[i]=W[f?n-j:j];
for(int i=0;i<n;i+=k<<1)
for(int j=0;j<k;j++){
ll x=a[i+j],y=w[j]*a[i+j+k]%inf;
reduce(a[i+j]=x+y-inf);reduce(a[i+j+k]=x-y);
}
}
if(f)inc(i,0,n-1)a[i]=a[i]*invn%inf;
}
ll _a[NM];
void inv(ll*b,ll*a,int m){
if(m==1){b[0]=qpow(a[0],inf-2);return;}
inv(b,a,m+1>>1);init(m<<1);
copy(a,a+m,_a);clear(_a+m,_a+lim);clear(b+(m+1)/2,b+lim);
fft(b);fft(_a);
inc(i,0,lim-1)b[i]=b[i]*(2-_a[i]*b[i]%inf+inf)%inf;
fft(b,1);
}
void ln(ll*b,ll*a,int m){
inv(b,a,m);
inc(i,0,m-2)_a[i]=a[i+1]*(i+1)%inf;
init(m<<1);
clear(_a+m-1,_a+lim);clear(b+m,b+lim);
fft(_a);fft(b);
inc(i,0,lim-1)b[i]=b[i]*_a[i]%inf;
fft(b,1);
dec(i,m-1,1)b[i]=b[i-1]*::inv[i]%inf;b[0]=0;
}
ll _b[NM];
void exp(ll*b,ll*a,int m){
if(m==1){b[0]=1;return;}
exp(b,a,m+1>>1);
clear(b+(m+1)/2,b+m);
ln(_b,b,m);
inc(i,0,m-1)reduce(_b[i]=a[i]-_b[i]);_b[0]++;
clear(_b+m,_b+lim);clear(b+m,b+lim);
fft(_b);fft(b);
inc(i,0,lim-1)b[i]=b[i]*_b[i]%inf;
fft(b,1);
}
}


int main(){
n=read();m=read();
inv[1]=1;
inc(i,2,m)inv[i]=inv[inf%i]*(inf-inf/i)%inf;
inc(i,1,n)v[read()]++;
inc(i,1,m)if(v[i])
for(int j=i,k=1;j<=m;j+=i,k++)a[j]+=inv[k]*v[i],a[j]%=inf;
Poly::exp(b,a,m+1);
inc(i,1,m)printf("%lld\n",b[i]);
return 0;
}