hdu6593(斯特林数+多项式多点求值)

题目链接

http://acm.hdu.edu.cn/status.php?first=&pid=&user=qkoqhh&lang=0&status=0

题意

给定 $n$ 和一个函数 $\displaystyle f(x)=\frac{b}{c+e^{ax+d}}$ ,令 $ax+d=0$ 的解为 $x_0$ ,将 $f(x)$ 在 $x_0$ 处展开(模 $998244353$ 下)

给定 $m$ 组询问,每组询问给定 $f(x)$ 的四个参数 $a,b,c,d$ ,要求 $f(x)$ 的 $n$ 次项系数

题解

感觉这个题比较教科书吧。。所以就上去干了一发。。

首先要把 $f(x)$ 展开,展开的方式窝和题解不太一样

这里有个注意的地方是除了 $c$ ,所以当 $c=0$ 的时候要另做讨论

这个问题倒是不大。。

所以当 $c\neq 0$ 时,要求的就是

然后后面那个和式比较令人头痛啊。。幂级数乘等比的求和感觉也只能用错位相减。。然而做出差来不像等比一样是个常数就很尴尬。。

因此考虑做差比较方便的下降幂函数,那么设$S(q,k)=\sum_{n=0}^{\infty}n^{\underline k}q^n$ ,做错位相减得

然后代入上式

对多次询问,由于 $n$ 是相同的,所以可以先预处理斯特林数构造多项式,然后变成一个多点求值问题。。


后记:错位相减法杀我啊啊啊啊




代码

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/**
*         ┏┓    ┏┓
*         ┏┛┗━━━━━━━┛┗━━━┓
*         ┃       ┃  
*         ┃   ━    ┃
*         ┃ >   < ┃
*         ┃       ┃
*         ┃... ⌒ ...  ┃
*         ┃ ┃
*         ┗━┓ ┏━┛
*          ┃ ┃ 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 140005
#define nm 400005
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;
}

namespace Poly{
int lim,bit,rev[NM],w[NM],W[NM];
ll invn;
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,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);clear(b+m,b+lim);
}
ll _b[NM];
void div(ll*c,ll*d,ll*a,ll*b,int n,int m){
reverse_copy(a,a+n,c);reverse_copy(b,b+m,d);
inv(_b,d,n-m+1);reverse(d,d+m);
init(n-m+1<<1);clear(c+n-m+1,c+lim);
fft(_b);fft(c);
inc(i,0,lim-1)c[i]=c[i]*_b[i]%inf;
fft(c,1);
reverse(c,c+n-m+1);clear(c+n-m+1,c+lim);
init(n);
copy(c,c+n-m+1,_b);clear(_b+n-m+1,_b+lim);
m--;clear(d+m,d+lim);
fft(_b);fft(d);
inc(i,0,lim-1)d[i]=d[i]*_b[i]%inf;
fft(d,1);
clear(d+m,d+lim);clear(_b,_b+lim);
inc(i,0,m-1)reduce(d[i]=a[i]-d[i]);
}
vector<ll>p[NM],q[NM];ll _c[NM];
void build(int i,int x,int y,const ll*a){
if(x==y){p[i].clear();p[i].push_back(inf-a[x]);p[i].push_back(1);return;}
build(i<<1,x,mid,a);build(i<<1|1,mid+1,y,a);
int n=p[i<<1].size(),m=p[i<<1|1].size();
init(n+m-1);
copy(p[i<<1].begin(),p[i<<1].end(),_a);clear(_a+n,_a+lim);
copy(p[i<<1|1].begin(),p[i<<1|1].end(),_b);clear(_b+m,_b+lim);
fft(_a);fft(_b);
inc(j,0,lim-1)_c[j]=_a[j]*_b[j]%inf;
fft(_c,1);p[i].assign(_c,_c+n+m-1);
}
ll _d[NM],tmp[NM],ret[NM];
void DIV(int x,int y){
if(q[x].size()<p[y].size()){q[y]=q[x];return;}
copy(q[x].begin(),q[x].end(),_c);copy(p[y].begin(),p[y].end(),_d);
div(tmp,ret,_c,_d,q[x].size(),p[y].size());
q[y].assign(ret,ret+p[y].size()-1);
while(!q[y].back())q[y].pop_back();
}
void cal(int i,int x,int y,ll*a){
if(x==y){a[x]=q[i][0];return;}
DIV(i,i<<1);DIV(i,i<<1|1);
cal(i<<1,x,mid,a);cal(i<<1|1,mid+1,y,a);
}
void out(ll*a,int m){inc(i,0,m-1)printf("%lld%c",a[i]," \n"[i==m-1]);}
}

int n,m;
ll _x,_y,_t;
ll inv[NM],invp[NM],p[NM];
ll b[NM],c[NM],st[NM],a[NM],ans[NM];

void init(){
inc(i,0,n)if(i&1)a[i]=inf-invp[i];else a[i]=invp[i];
inc(i,0,n)st[i]=qpow(i,n)*invp[i]%inf;
Poly::init(n<<1|1);
Poly::clear(a+n+1,a+Poly::lim);
Poly::clear(st+n+1,st+Poly::lim);
Poly::fft(a);Poly::fft(st);
inc(i,0,Poly::lim-1)st[i]=st[i]*a[i]%inf;
Poly::fft(st,1);
}

int main(){
n=5e4;p[0]=p[1]=inv[1]=invp[0]=invp[1]=1;
inc(i,2,n)p[i]=p[i-1]*i%inf,inv[i]=inv[inf%i]*(inf-inf/i)%inf,invp[i]=invp[i-1]*inv[i]%inf;
while(~scanf("%d%d",&n,&m)){
inc(i,1,m){
reduce(_x=read()%inf);reduce(_y=read()%inf);reduce(_t=read()%inf);read();
b[i]=qpow(_t+1,inf-2);
c[i]=qpow(_x,n)*_y%inf*b[i]%inf*invp[n]%inf;
}
init();
inc(i,0,n)if(i&1)a[i]=inf-st[i]*p[i]%inf;else a[i]=st[i]*p[i]%inf;
//Poly::out(a,n+1);
Poly::build(1,1,m,b);
Poly::q[0].assign(a,a+n+1);
Poly::DIV(0,1);
Poly::cal(1,1,m,ans);
inc(i,1,m)ans[i]=ans[i]*c[i]%inf;
//inc(i,1,m)printf("%lld ",ans[i]);putchar('\n');
inc(i,1,m)if(b[i]==1){
if(n&1)printf("%lld\n",(inf-c[i])%inf);
else printf("%lld\n",c[i]);
}else if(b[i]==0)printf("-1\n");
else printf("%lld\n",ans[i]);
}
return 0;
}