- 有一个很妙的转化:对每个section随机一个[0,1]内的实数\(p_*\),然后按这些数从小到大考虑每个section。将sections编号为\((-\inf,+\inf)\),考虑0号section,它舒服当且仅当左边的递增段长度、右边的递减段长度均为偶数(不算点0,即要满足区间[l,-1]和区间[1,r]长度均为偶数)。设\(p_0=1-x\),可以推出概率密度函数\((P(p_0>p_1)+P(p_0<p_1<p_2>p_3)+…)^2=e^{-2x}\)。
- 然后本题就只需要一个DP。设f(i,x,le,ev,od)表示\(\forall j≤i\)的\(p_j\)均已确定,\(p_i=x\),le表示左边递增段长度的奇偶性,ev、od分别表示右边递减段长度是否能为偶数、奇数,然后要使得[1,i]的照片符合s的概率。可以发现它是一个关于x的多项式,并且始终可以被表示成\(A(x)+\frac{B(x)}e+\frac C{e^x}\)的形式,其中\(A,B\)是有理多项式,\(C\)是有理数。那么可以一位一位地转移,分\(p_{i-1}<p{i}\)和\(p_{i-1}>p{i}\)两类讨论,要写两种积分。
- 最后算答案的时候,要算一个形如\(\int_0^1 A(x)e^{-x}\mathrm{d}x\)的东西,那么可以对每一项分别算,分部积分一下。要预处理一个\(S_i=\int_0^1 x^ie^{-x}\mathrm{d}x\),这个也可以分部积分。
- 由于我自己没写,这里就贴一份zys的代码。
(他都开了小地球大概不会见怪)
#include<cstdio>
#define Z int
#define C char
#define V void
#define L long long
#define T struct
#define S(n) scanf("%lld\n",&n)
#define P(n) printf("%lld ",(n+p)%p)
#define F(i,a,b) for(L i=a;i<=b;i++)
#define I if
#define E else
#define nx 1010
#define p 998244353
T poly{L a[nx],b[nx],c;}f[nx][2][2][2];//parity of left/even?/odd?
C a[nx];
L n,x,y,z,hf=p+1>>1,v[nx],s[nx][2];
V add(L&x,L y){(x+=y)%=p;}
V trans_bigger(poly x,poly&y){//f(y)=∫(0~y)f(x)dx
F(i,0,n-2)add(y.a[i+1],x.a[i]*v[i+1]),add(y.b[i+1],x.b[i]*v[i+1]);
add(y.a[0],x.c),add(y.c,-x.c);
}
V trans_smaller(poly x,poly&y){//f(y)=∫(y~1)f(x)dx
F(i,0,n-2)add(y.a[0],x.a[i]*v[i+1]),add(y.a[i+1],-x.a[i]*v[i+1]),add(y.b[0],x.b[i]*v[i+1]),add(y.b[i+1],-x.b[i]*v[i+1]);
add(y.b[0],-x.c),add(y.c,x.c);
}
Z main(){
freopen("hookplus.in","r",stdin);
freopen("hookplus.out","w",stdout);
n=nx-1,v[0]=v[1]=1;
F(i,2,n)v[i]=-p/i*v[p%i]%p;
//s[i]=∫(0~1)x^ie^(-x)dx=-1/e+i*s[i-1]
s[0][0]=1,s[0][1]=-1;
F(i,1,n)s[i][0]=i*s[i-1][0]%p,s[i][1]=(i*s[i-1][1]-1)%p;
S(n);
F(i,1,n)a[i]=getchar();
I(a[1]=='X')f[1][0][1][0].c=1;//left:even right:even value:e^(-x)
E{
f[1][0][0][1].c=1;//left:even right:odd value:e^(-x)
f[1][1][1][1].a[0]=1,f[1][1][1][1].c=-1;//left:odd right:either value:1-e^(-x)
}
F(i,1,n-1)F(le,0,1)F(ev,0,1)F(od,0,1){
L nle,nev,nod;
//p[i-1]<p[i]
nle=le^1,a[i+1]=='X'?(nod=0,nev=nle^1):(nod=1,nev=nle),nev&=ev,nod&=ev;
//transition
trans_bigger(f[i][le][ev][od],f[i+1][nle][nev][nod]);
//p[i-1]>p[i]
nle=0,a[i+1]=='X'?(nod=0,nev=nle^1):(nod=1,nev=nle),nev&=od,nod&=ev;
//transition
trans_smaller(f[i][le][ev][od],f[i+1][nle][nev][nod]);
}
F(le,0,1)F(ev,0,1)F(od,0,1){
poly g=f[n][le][ev][od];
I(ev){
F(i,0,nx-1)add(x,g.a[i]*s[i][0]),add(y,g.a[i]*s[i][1]);//∫(0~1)a(x)*e^(-x)dx
F(i,0,nx-1)add(y,g.b[i]*s[i][0]),add(z,g.b[i]*s[i][1]);//∫(0~1)b(x)/e*e^(-x)dx
add(x,g.c*hf),add(z,-g.c*hf);//∫(0~1)c*e^(-2x)dx
}
I(od){
F(i,0,nx-2)add(x,g.a[i]*v[i+1]),add(x,-g.a[i]*s[i][0]),add(y,-g.a[i]*s[i][1]);//∫(0~1)a(x)*(1-e^(-x))dx
F(i,0,nx-2)add(y,g.b[i]*v[i+1]),add(y,-g.b[i]*s[i][0]),add(z,-g.b[i]*s[i][1]);//∫(0~1)b(x)/e*(1-e^(-x))dx
add(x,g.c),add(y,-g.c),add(x,-g.c*hf),add(z,g.c*hf);//∫(0~1)c*e^(-x)(1-e^(-x))dx
}
}
P(x),P(y),P(z);
}