cf1153F(多项式展开)

题目链接

https://codeforces.com/contest/1153/problem/F

题意

随机在长度为 $l$ 的线段上取 $n$ 个区间,要求被至少 $m$ 个区间覆盖的部分的长度的期望值。线段由随机在 $l$ 上取两个点形成。

题解

比较少见的题,不过挺简单的。。

直接考虑单点贡献,那么答案为

其中 $p$ 为点 $x$ 被一条线段覆盖的概率,则有

答案为

从内到外层层用二项式展开成多项式即可,这里窝先展开成关于 $x^2+(l−x)^2$ 的多项式再展开成 $x$ 的多项式,复杂度为 $O(n^2)$




代码

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
/**
*         ┏┓    ┏┓
*         ┏┛┗━━━━━━━┛┗━━━┓
*         ┃       ┃  
*         ┃   ━    ┃
*         ┃ >   < ┃
*         ┃       ┃
*         ┃... ⌒ ...  ┃
*         ┃ ┃
*         ┗━┓ ┏━┛
*          ┃ ┃ 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<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 sqr(x) ((x)*(x))
#define mid (x+y)/2
#define NM 4005
#define nm 300005
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;
}




ll inv[NM],invp[NM],p[NM],l,_l,a[NM],b[NM],c[NM],d[NM],ans;
int n,m;
ll qpow(ll x,ll t){return t?qpow(sqr(x)%inf,t>>1)*(t&1?x:1ll)%inf:1ll;}

int main(){
n=read();m=read();l=read();_l=sqr(l)%inf;
p[0]=p[1]=inv[1]=invp[0]=invp[1]=1;
inc(i,2,n*2+1)p[i]=p[i-1]*i%inf,inv[i]=inv[inf%i]*(inf-inf/i)%inf,invp[i]=invp[i-1]*inv[i]%inf;
a[0]=1;
inc(k,1,n){
mem(b);
inc(i,0,n)b[i+1]=-a[i];
inc(i,0,n)b[i]+=a[i]*_l%inf,b[i]%=inf;
inc(i,0,n)a[i]=(b[i]+inf)%inf;
if(k<m)continue;
inc(i,0,n)c[i+n-k]+=b[i]*p[n]%inf*invp[k]%inf*invp[n-k]%inf,c[i+n-k]%=inf;
}
mem(a);a[0]=1;d[0]=c[0];
inc(k,1,n){
mem(b);
inc(i,0,n*2)b[i]=a[i]*_l%inf;
inc(i,0,n*2)b[i+1]+=inf-2*l%inf*a[i]%inf,b[i+1]%=inf;
inc(i,0,n*2)b[i+2]+=2*a[i]%inf,b[i+2]%=inf;
inc(i,0,n*2)a[i]=b[i];
inc(i,0,n*2)d[i]+=c[k]*a[i]%inf,d[i]%=inf;
}
for(int k=0,t=l;k<=2*n;k++,t=t*l%inf)ans+=d[k]*t%inf*inv[k+1]%inf,ans%=inf;
ans*=qpow(qpow(_l,n),inf-2);ans%=inf;if(ans<0)ans+=inf;
printf("%lld\n",ans);
return 0;
}