ARC 124 F Chance Meeting 题解

ARC 124 F Chance Meeting 题解

一个有趣的计数题。

首先可以发现上下走和向右走是独立的。

然后问题转变成有\(m-1\)\(1\)\(m-1\)\(-1\)排成一行,令\(pre_i\)为前缀和。

你需要把它切成\(2*n-1\)段可以为空。

令第\(i\)段为\([l_i,r_i],(l_i\leq r_i+1,r_i=l_{i+1}-1)\)

需要满足\((\sum_{i\in [l_n-1,r_n]}[pre_i=0])=1\)

可以先搞一个数组,记录\(+-\)序列的前缀和只有最后一个是\(0\)的方案数。

然后计算原问题只需要容斥掉最后一段不符合的就好了,这是一个卷积的形式。

时间复杂度为\(O(n\log n)\)

code(一些板子就略去了):

int n,m;
vector<int> single;
vector<int> Half;
int D(int A,int B){
    return comb(A+B-1,B-1);
}
int main(){
    genmath();
    scanf("%d%d",&n,&m);
    m--;
    single=vector<int> (m+1,0);
    rb(i,1,m){
        if(i==1)
            single[i]=2;
        else
            single[i]=2ll*(comb(i+i-2,i-1)-comb(i+i-2,i-2)+MOD)%MOD;
    }
    Half=vector<int> (m+1,0);
    rb(i,0,m){
        Half[i]=1ll*comb(i+i,i)*D(i*2,n)%MOD;
    }
    auto Tmp=Half*single;
    rb(i,0,m) Half[i]=(Half[i]-Tmp[i]+MOD)%MOD;
    Half=Half*Half;
    int ans=1ll*Half[m]*comb(2*n-2,n-1)%MOD;
    cout<<ans<<endl;
    return 0;
}
posted @ 2021-10-22 16:47  WWW~~~  阅读(69)  评论(0)    收藏  举报