peiwenjun's blog 没有知识的荒原

ARC111F Do you like query problems? 题解

题目描述

一个长为 \(n\) 的序列 \(a\) ,初始全为 \(0\)

接下来 \(q\) 次操作:

  • 1 l r v :对 \(\forall l\le i\le r\) ,令 \(a_i\gets\min(a_i,v)\)
  • 2 l r v :对 \(\forall l\le i\le r\) ,令 \(a_i\gets\max(a_i,v)\)
  • 3 l r :输出 \(\sum_{i=l}^ra_i\)

其中 \(1\le l\le r\le n,0\le v\lt m\)

你需要统计所有 \(\big((2m+1)\cdot\frac{n(n+1)}2\big)^q\) 个操作序列中,所有输出答案的和。

数据范围

  • \(1\le n,m,q\le 2\cdot 10^5\)

时间限制 \(\texttt{4s}\) ,空间限制 \(\texttt{1GB}\)

分析

显然拆成每个位置算贡献。

\(T=(2m+1)\cdot\frac{n(n+1)}2\) ,先算期望,最后乘上 \(T^q\) 即可。

\(\forall 1\le j\le n\) ,记 \(f_{i,k}\) 为经过 \(i\) 次操作后, \(a_j=k\) 的概率, \(p_j=\frac{j(n-j+1)}{\frac{n(n+1)}2}\) 为区间 \([l,r]\) 包含 \(j\) 的概率。

  • 如果 \(j\) 没有落在 \([l,r]\) 内,显然 \(a_j\) 不会变化。
  • 如果 \(j\) 落在 \([l,r]\) 内,综合前两种操作,有 \(m\) 种操作方法可以将 \(a_j\) 分别变成 \(0,1,\cdots,m-1\) ,另 \(m\) 种方法 \(a_j\) 不会变化。当然,如果操作为询问, \(a_j\) 也不会变化。

转移方程为:

\[f_{i,k}=p_j\cdot\frac1{2m+1}\sum_{x=0}^{m-1}f_{i-1,x}+(1-p_j\cdot\frac m{2m+1})f_{i-1,k} \]

初始值 \(f_{0,0}=1\) ,统计答案枚举询问位置:

\[ans=\sum_{j=1}^n\sum_{i=1}^q\sum_{k=0}^{m-1}k\cdot p_j\cdot\frac1{2m+1}\cdot f_{i-1,k} \]

于是我们得到了一个\(O(nmq)\)的做法。


观察上面的转移方程,发现 \(k=1,2,\cdots,m-1\) 的地位相等。

重新设计状态, \(f_i\) 表示经过 \(i\) 次操作后, \(a_i=0\) 的概率。则 \(\forall 1\le i\lt m\)\(f_i=k\) 的概率为 \(\frac{1-f_i}{m-1}\)

转移方程:

\[f_i=(1-p_j\cdot\frac m{2m+1})f_{i-1}+p_j\cdot\frac1{2m+1} \]

\(i\) 次操作对答案的贡献:

\[p_j\cdot\frac1{2m+1}\sum_{k=1}^{m-1}k\cdot\frac{1-f_{i-1}}{m-1}=p_j\cdot\frac m{2(2m+1)}(1-f_{i-1}) \]

一阶线性递推,并且转移系数与 \(i\) 无关,矩阵快速幂优化:

\[\begin{bmatrix} f_{i-1}&ans&1\\ \end{bmatrix} \times \begin{bmatrix} 1-p_j\cdot\frac m{2m+1}&-p_j\cdot\frac m{4m+2}&0\\ 0&1&0\\ p_j\cdot\frac1{2m+1}&p_j\cdot\frac m{4m+2}&1\\ \end{bmatrix} = \begin{bmatrix} f_i&ans'&1 \end{bmatrix} \]

时间复杂度 \(\mathcal O(n\log q)\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=2e5+5,mod=998244353;
int m,n,q,t,res;
struct mat
{
    int v[3][3];
};
mat operator*(const mat &a,const mat &b)
{
    static mat c;
    for(int i=0;i<=2;i++)
        for(int j=0;j<=2;j++)
        {
            c.v[i][j]=0;
            for(int k=0;k<=2;k++) c.v[i][j]=(c.v[i][j]+a.v[i][k]*b.v[k][j])%mod;
        }
    return c;
}
int qpow(int a,int k)
{
    int res=1;
    while(k)
    {
        if(k&1) res=res*a%mod;
        a=a*a%mod,k>>=1;
    }
    return res;
}
mat qpow(mat a,int k)
{
    mat res={1,0,1,0,0,0,0,0,0};
    while(k)
    {
        if(k&1) res=res*a;
        a=a*a,k>>=1;
    }
    return res;
}
signed main()
{
    scanf("%lld%lld%lld",&n,&m,&q),t=(2*m+1)*n*(n+1)/2%mod;
    for(int j=1,tmp=m*(mod+1)/2%mod;j<=n;j++)
    {
        int p=j*(n+1-j)%mod*qpow(t,mod-2)%mod;
        mat mul={(1-p*m)%mod,-p*tmp%mod,0,0,1,0,p,p*tmp%mod,1};
        res=(res+qpow(mul,q).v[0][1])%mod;
        /**for(int i=1,x=1;i<=q;i++)
        {
            res=(res+p*tmp%mod*(1-x))%mod;
            x=((1-p*m)%mod*x+p)%mod;
        }**/
    }
    printf("%lld\n",(res+mod)*qpow(t,q)%mod);
    return 0;
}

posted on 2023-02-15 19:37  peiwenjun  阅读(7)  评论(0)    收藏  举报

导航