2025.6.28 模拟赛

6.28 模拟赛

zephyr

显然可以钦定 \(S_1=1\),于是字符串只有一种情况 \(S_i=[z_i>0]\),只需判断这个字符串是否符合要求。

这样就有了若干平方暴力/哈希做法。

来一个确定性的 \(O(n\log^2)\) 做法。

记反串为 \(T\),每个位置建一个点,对钦定相同的关系连边。则每个限制形如若干 \(S-S,T-T\) 的边加上最后的 \(S-T\) 的边,最后只需判断 \(S_1,T_1\) 是否联通。

\(b_i=\min\limits_{t\in [0,m]} z_i\),则有 \(b_i\) 条边是一直不变的,而会变化的边总数是 \(O(m)\) 的。

对于不变的边,发现是形如 \([l,r]\to [1,r-l+1]\) 这样区间连的,可以用倍增并查集维护。
具体的,维护 $\log $ 个并查集,分别表示 \([i,i+2^k-1]\) 的连边。所有边连完后再逐层递归到子区间。

struct dsu{
    int fa[N][21],n;
    inline void init(int _n){
        n=_n;rep(j,0,19) rep(i,1,n+1) fa[i][j]=i;
    }
    inline int getfa(int x,int k){
        return fa[x][k]==x?x:fa[x][k]=getfa(fa[x][k],k);
    }
    inline void merge(int x,int y,int k){
        int fx=getfa(x,k),fy=getfa(y,k);
        if(fx==fy) return;
        fa[fx][k]=fy;
    }
    inline void MERGE(){
        per(k,19,1) {
            rep(i,1,n-(1<<k)+1){
                int j=getfa(i,k);if(i==j) continue;
                merge(i,j,k-1);
                merge(i+(1<<(k-1)),j+(1<<(k-1)),k-1);
            } 
        }
    }
}d;

对于变化的边,把 \(z_i\) 的变化曲线拉出来,每条边的存在都是若干区间,直接套线段树分治即可。

由于数据范围过大,跑的非常慢,需要加一个当前 \(S_1,T_1\) 已经联通就不继续递归的小优化。

print

钦定第一次操作 \([1,m]\),断环为链,此时 \([1,m]\) 是黑的,\([m+1,n]\) 是白的。

期望拆成概率,这次的拆法是第 \(i\) 次操作还没结束的概率。

判断完全覆盖是相邻两个操作的距离不超过 \(m\),此时有重复操作就很麻烦,于是考虑只算“有效操作”,然后乘上一个 \(i\) 次有效操作后再做一次有效操作的期望步数 \(\frac{n}{n-i-1}\)



posted @ 2025-06-30 21:19  Cindy_Li  阅读(12)  评论(0)    收藏  举报