Description
有n个随机变量xi,第i个在[li,ri]内均匀随机,问max((∑xi)^k,a ^k)的期望
n<=50,-2000<=li<=ri<=2000
Solution
先把li累加起来,每个xi变成在[0,len[i]]内均匀随机
设
F
i
(
x
)
F_i(x)
Fi(x)表示
∑
j
=
1
i
x
j
\sum_{j=1}^{i}xj
∑j=1ixj的概率密度函数
则有
F
i
(
x
)
=
∫
x
−
l
e
n
i
x
F
i
−
1
(
y
)
d
y
F_i(x)=\int_{x-len_i}^xF_{i-1}(y)dy
Fi(x)=∫x−lenixFi−1(y)dy
显然
F
i
(
x
)
F_i(x)
Fi(x)是一个分段函数,考虑维护每一段
为了方便我们可以直接设[i,i+1]为一段
然后根据积分的意义这一个东西是可以直接求的
考虑求答案只需要算
∫
l
r
F
n
(
x
)
x
k
d
x
\int _l^rF_n(x)x^kdx
∫lrFn(x)xkdx这个也可以直接算
就是有点难写
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef vector<int> poly;
const int N=55,M=2e5+5,Mo=998244353;
int pwr(int x,int y) {
int z=1;
for(;y;y>>=1,x=(ll)x*x%Mo)
if (y&1) z=(ll)z*x%Mo;
return z;
}
void inc(int &x,int y) {x=x+y>=Mo?x+y-Mo:x+y;}
void dec(int &x,int y) {x=x-y<0?x-y+Mo:x-y;}
int Abs(int x) {return x<0?-x:x;}
int n,K,a,s,l,r,ct,sum[M],R,inv[N],It[M],pw[N],C[N][N];
poly p[M],q[M],pl;
int Integral (poly a) {
int ans=0;
for(int i=0;i<a.size();i++) inc(ans,(ll)inv[i+1]*a[i]%Mo);
return ans;
}
void trans(int len) {
fo(i,R,R+len-1) p[i].resize(0);R+=len;
fo(i,0,R-1) It[i]=Integral(p[i]);
sum[0]=It[0];fo(i,1,R-1) sum[i]=(sum[i-1]+It[i])%Mo;
fo(i,0,R-1) {
int j=i-len;
q[i].resize(p[i].size()+1);q[i][0]=0;
for(int k=1;k<q[i].size();k++) q[i][k]=(ll)p[i][k-1]*inv[k]%Mo;
if (i>0) inc(q[i][0],sum[i-1]);
if (j>=0) {
if (j>0) dec(q[i][0],sum[j-1]);
pl.resize(p[j].size()+1);pl[0]=0;
for(int k=0;k<p[j].size();k++) pl[k+1]=(ll)p[j][k]*inv[k+1]%Mo;
while (q[i].size()<pl.size()) q[i].push_back(0);
for(int k=1;k<pl.size();k++) dec(q[i][k],pl[k]);
}
}
int inv=pwr(len,Mo-2);
fo(i,0,R-1) {
p[i].resize(q[i].size());
for(int j=0;j<p[i].size();j++) p[i][j]=(ll)q[i][j]*inv%Mo;
}
}
int len[N];
int main() {
freopen("power.in","r",stdin);
freopen("power.out","w",stdout);
scanf("%d%d%d",&n,&K,&a);bool fir=0;int sl=0;
inv[0]=inv[1]=1;fo(i,2,n) inv[i]=(ll)(Mo-Mo/i)*inv[Mo%i]%Mo;
fo(i,1,n) {
scanf("%d%d",&l,&r);
len[i]=r-l;sl+=l;
}
sort(len+1,len+n+1);
fo(i,1,n) {
if (!len[i]) continue;
if (!fir) {
int iv=pwr(len[i],Mo-2);
fo(j,0,len[i]-1) p[j].resize(1),p[j][0]=iv;
R=len[i];fir=1;
} else trans(len[i]);
}
if (!fir) {
if (K&1) printf("%d\n",(sl>=a)?pwr(sl,K):pwr(a,K));
else printf("%d\n",(Abs(sl)>=Abs(a))?pwr(sl,K):pwr(a,K));
return 0;
}
fo(i,0,n) {
C[i][0]=1;
fo(j,1,i) C[i][j]=(C[i-1][j]+C[i-1][j-1])%Mo;
}
if (K&1) {
int ans=0;
fo(i,0,R-1)
if (i+sl>=a) {
pl.clear();pl.resize(p[i].size());int id=((i+sl)+Mo)%Mo;
pw[0]=1;for(int j=1;j<p[i].size();j++) pw[j]=(ll)pw[j-1]*id%Mo;
for(int k=0;k<p[i].size();k++)
fo(j,0,k) {
int now=(ll)p[i][k]*C[k][j]%Mo*pw[k-j]%Mo;
if ((k-j)&1) dec(pl[j],now);
else inc(pl[j],now);
}
for(int k=0;k<pl.size();k++) {
int ret=(pwr(id+1,k+K+1)-pwr(id,k+K+1)+Mo)%Mo;
inc(ans,(ll)pl[k]*pwr(k+K+1,Mo-2)%Mo*ret%Mo);
}
} else inc(ans,(ll)Integral(p[i])*pwr(a,K)%Mo);
printf("%d\n",ans);
} else {
int ans=0;
fo(i,0,R-1)
if (Abs(i+sl)>=Abs(a)&&Abs(i+sl+1)>=Abs(a)) {
pl.clear();pl.resize(p[i].size());
pw[0]=1;for(int j=1;j<p[i].size();j++) pw[j]=(ll)pw[j-1]*(i+sl)%Mo;
for(int k=0;k<p[i].size();k++)
fo(j,0,k) {
int now=(ll)p[i][k]*C[k][j]%Mo*pw[k-j]%Mo;
if ((k-j)&1) dec(pl[j],now);
else inc(pl[j],now);
}
for(int k=0;k<pl.size();k++) {
int ret=(pwr(i+sl+1,k+K+1)-pwr(i+sl,k+K+1)+Mo)%Mo;
inc(ans,(ll)pl[k]*pwr(k+K+1,Mo-2)%Mo*ret%Mo);
}
} else inc(ans,(ll)Integral(p[i])*pwr(a,K)%Mo);
printf("%d\n",ans);
}
return 0;
}