Loading

【考后总结】6 月 NOI 模拟赛 6

Page Views Count

6.27 冲刺国赛模拟 25

T1 简单计数

不是古典概型所以不能方案数相除。

考虑枚举第一个选择的位置 \(i\),这样分成两个独立的区间,只关心 \(k\) 所在的一个,转移方程:

\[f_{n,k}=\dfrac{1}{n-1}\left([k<n]+[k>1]+\sum_{i>k}f_{i-1,k}+\sum_{i<k-1}f_{n-(i+1),k-(i+1)}\right) \]

前缀和优化可以做到 \(O(T+n^2)\)

注意到 \(k\) 的限制可以看作两个区间拼起来,具体是 \([1,k]\)\([k,n]\)\(k\) 没有被选择的概率就是在两个中都没有被选择的概率乘积,这两个事件显然独立。

再注意到此时 \(k\) 就是边界位置了,而 \(f_{n,1}=f_{n,n}\) 所以只需要求出 \(f_{i,1}\) 就行了,答案就是 \(f_{n,k}=1-(1-f_{k,1})(1-f_{n-k+1,1})\),复杂度 \(O(T+n)\)

点击查看代码
inline int q_pow(int A,int B,int P){
    int res=1;
    while(B){
        if(B&1) res=1ll*res*A%P;
        A=1ll*A*A%P;
        B>>=1;
    }
    return res;
}

int t;
int n,k;
int inv[maxn];
int f[maxn],g[maxn];

int main(){
    freopen("count.in","r",stdin);
    freopen("count.out","w",stdout);
    inv[1]=1;
    for(int i=2;i<=lim;++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    f[1]=0,f[2]=1;
    int sum=0;
    for(int i=3;i<=lim;++i){
        sum=(sum+f[i-2])%mod;
        f[i]=1ll*inv[i-1]*(1+sum)%mod;
    }
    t=read();
    while(t--){
        int n=read(),k=read();
        printf("%lld\n",(1ll-1ll*(1-f[k]+mod)*(1-f[n-k+1]+mod)%mod+mod)%mod);
    }
    return 0;
}
posted @ 2023-06-27 20:13  SoyTony  阅读(35)  评论(0编辑  收藏  举报