首先 “被经过的整点的期望个数” 不好求,我们可以把它看成 “每个整点被经过的概率的和”。
对于某个整点,求 “它被任意一个人经过的概率” 不好求,我们可以求 “它不被任意一个人经过的概率”,那么现在的问题是求某个整点不被某个人经过的概率,或者说求某个整点被某个人经过的概率。
把这个人看作原点,然后设这个整点的坐标为 \(i\)(不妨设 \(i\geq 0\),\(i<0\) 同理)。考虑转化到坐标-时间图像上,现在问题转化为:从原点开始走,每一步能往右上/右下走,求走 \(n\) 步,过程中碰到直线 \(y=i\) 的走法方案数,最后除个 \(2^n\) 即为概率。
(本文所有图片均引用自题解的 PPT)
类似卡特兰数,我们考虑翻折:对于一条碰到 \(y=i\) 且终点 \(j<i\) 的折线,我们找到它第一次碰到 \(y=i\) 的位置,并把这条折线在这个位置之后的所有部分都沿 \(y=i\) 做翻折,那么就得到了一条终点在 \(j'>i\) 的折线:
而且显然任意一条终点在 \(j'>i\) 的折线,都唯一对应着一条终点在 \(j'\) 的折线(它自己),以及一条终点在 \(j\) 的折线(上述翻折过程的逆过程得到的折线)。
那么如果设 \(E(i)\) 表示终点在 \(i\) 的走法方案数,那么碰到直线 \(y=i\) 的走法方案数即为:
\[E(i)+2\sum_{j>i} E(j) \]\(E(i)\) 也比较好求:容易得到终点在 \(i\) 需要向上走 \(\frac{n+i}{2}\) 步,于是 \(E(i)=[n\equiv i\pmod 2]\dbinom{n}{\frac{n+i}{2}}\)。
那么我们直接枚举每一个可能经过的整点(\(O(nm)\) 个),再对枚举的整点枚举每一个人,时间复杂度 \(O(nm^2)\)。
#include<bits/stdc++.h>
#define M 25
#define N 12000010
#define fi first
#define se second
#define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
#define INF 0x7fffffff
using namespace std;
namespace modular
{
const int mod=998244353;
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int dec(int x,int y){return x-y<0?x-y+mod:x-y;}
inline int mul(int x,int y){return 1ll*x*y%mod;}
}using namespace modular;
inline int poww(int a,int b)
{
int ans=1;
while(b)
{
if(b&1) ans=mul(ans,a);
a=mul(a,a);
b>>=1;
}
return ans;
}
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^'0');
ch=getchar();
}
return x*f;
}
int n,m,x[M];
int fac[N],ifac[N],E[N];
vector<pii>part;
int C(int n,int m)
{
return mul(mul(fac[n],ifac[m]),ifac[n-m]);
}
int calc(int now)
{
int p=1;
for(int i=1;i<=m;i++)
if(abs(now-x[i])<=n)
p=mul(p,dec(1,E[abs(now-x[i])]));
return dec(1,p);
}
int main()
{
n=read(),m=read();
int inv=poww(poww(2,n),mod-2);
fac[0]=1;
for(int i=1;i<=n;i++) fac[i]=mul(fac[i-1],i);
ifac[n]=poww(fac[n],mod-2);
for(int i=n;i>=1;i--) ifac[i-1]=mul(ifac[i],i);
int sum=0;
for(int i=n;i>=0;i--)
{
int nowE=0;
if(!((i&1)^(n&1))) nowE=mul(inv,C(n,(n+i)/2));
E[i]=add(nowE,mul(sum,2));
sum=add(sum,nowE);
}
for(int i=1;i<=m;i++)
{
x[i]=read();
part.push_back(mk(x[i]-n,x[i]+n));
}
sort(part.begin(),part.end());
int lstr=-INF,ans=0;
for(pii now:part)
{
int l=now.fi,r=now.se;
l=max(l,lstr+1);
for(int i=l;i<=r;i++)
ans=add(ans,calc(i));
lstr=max(lstr,r);
}
printf("%d\n",ans);
return 0;
}
/*
2 1
1
*/
标签:ch,期望,整点,int,逃亡,mul,XSY3395,sum,define
From: https://www.cnblogs.com/ez-lcw/p/16840755.html