题解:客星璀璨之夜
基本思路:
一道不错的概率与期望题。
考虑每段距离对答案的贡献。
每段距离以他右边的行星编号为编号,编号为\(2~2n+1\)。
可以发现,当两颗行星湮灭后,就变成了\(n-1\)的情况所以这实际上是可以递推的。
记\(f[i][j]\)表示情况为\(2i+1\)时第\(j\)条距离产生贡献的概率。
一条距离产生贡献,当且仅当有球经过。
可以是一开始的时候他左右的球经过他。
也可以是一些球湮灭后,其他球相互湮灭时经过他,这些球不一定一开始时在他两端。
接下来考虑转移方程:
枚举是那些球移动导致\(i\)向\(i-1\)变化,然后由\(i-1\)到推至\(i\)。
记\(j\)为边的编号
1.移动的球的编号是小于j-1的:
\[f[i][j]=(f[i][j]+f[i-1][j-2]*inv[i]); \]2.移动的球是j-1:
\[f[i][j]=(f[i][j]+f[i-1][j-2]*inv[i<<1]+(inv[2]+inv[2]*f[i-1][j-1])*inv[i]); \]3.移动的球是j
\[f[i][j]=(f[i][j]+(inv[2]+inv[2]*f[i-1][j-1])*inv[i]+inv[i<<1]*f[i-1][j]); \]4.移动的球比j大
\[f[i][j]=(f[i][j]+f[i-1][j]*inv[i]); \]
考虑球湮灭后当前距离会到\(i-1\)情况的那一段距离中贡献,从那个编号的边转移来。
\(j-1\)与\(j\)的情况,由于移动的球在移动时有50%的概率经过这段距离,所以除了上面正常的累加外,还要累加一个50%。
在取模意义下,所有除法写为乘逆元的形式。
代码
#include<bits/stdc++.h>
using namespace std;
namespace STD
{
#define rr register
#define inf INT_MAX
typedef long long ll;
const int N=3004;
const ll mod=998244353;
int n;
ll x[N<<1];
ll f[N][N<<1];
ll inv[N<<1];
ll read()
{
rr ll x_read=0,y_read=1;
rr char c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read=-1;
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=(x_read<<3)+(x_read<<1)+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
void pre()
{
inv[0]=inv[1]=1;
for(rr int i=2;i<=(N<<1);i++)
inv[i]=((mod-mod/i)*inv[mod%i])%mod;
}
};
using namespace STD;
int main()
{
pre();
n=read();
for(rr int i=1;i<=(n<<1)+1;i++)
x[i]=read();
for(rr int i=2;i<=3;i++)
f[1][i]=inv[2];
for(rr int i=2;i<=n;i++)//枚举第几层
{
for(rr int j=2;j<=(i<<1)+1;j++)//枚举哪条边
{
ll x1,x2=((i<<1)+1-j)>>1;
x1=i-1-x2;
f[i][j]=(f[i][j]+x1*f[i-1][j-2]%mod*inv[i]%mod)%mod;
if(j&1)
f[i][j]=((f[i][j]+f[i-1][j-2]*inv[i<<1]%mod)%mod+(inv[2]+inv[2]*f[i-1][j-1]%mod)%mod*inv[i]%mod)%mod;
else
f[i][j]=((f[i][j]+(inv[2]+inv[2]*f[i-1][j-1]%mod)%mod*inv[i]%mod)%mod+inv[i<<1]*f[i-1][j])%mod;
f[i][j]=(f[i][j]+x2*f[i-1][j]%mod*inv[i]%mod)%mod;
}
}
ll ans=0;
for(rr int i=2;i<=((n<<1)+1);i++)
ans=(ans+(x[i]-x[i-1])*f[n][i]%mod)%mod;
printf("%lld\n",ans);
}
后言:
代码中提供了一个优化,因为原思路直接打的话是\(O(n^{3})\),会\(T\),可以计算一下累加的次数,将循环变为一个乘法,就能到\(O(n^{2})\)。
2021-07-31 06:29:11 星期六 现役