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_{0,0}=1\) ,统计答案枚举询问位置:
于是我们得到了一个\(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}\) 。
转移方程:
第 \(i\) 次操作对答案的贡献:
一阶线性递推,并且转移系数与 \(i\) 无关,矩阵快速幂优化:
时间复杂度 \(\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;
}
本文来自博客园,作者:peiwenjun,转载请注明原文链接:https://www.cnblogs.com/peiwenjun/p/17124435.html
浙公网安备 33010602011771号