「SOL」Do you like query problems?(AtCoder)

還差不少ide


# 題面

有一個長度爲 \(n\) 的數列 \(\{a_1,a_2,\dots,a_n\}\) 和一個整數 \(b\),初始 \(a_i=0,b=0\)\(a_i\) 值域爲 \([0,m-1]\)。進行 \(Q\) 次操做,每次操做是下列全部操做中的一種:spa

  • A l r v:對 \(i\in[l,r]\)\(a_i\leftarrow\max\{a_i,v\}\),這種操做一共包含 \(m\times \frac{n(n+1)}{2}\) 種;
  • B l r v:對 \(i\in[l,r]\)\(a_i\leftarrow\min\{a_i,v\}\),這種操做一共包含 \(m\times \frac{n(n+1)}{2}\) 種;
  • C l r\(b\leftarrow b+\sum_{i=l}^ra_i\),這種操做一共包含 \(\frac{n(n+1)}2\) 種。

\(Q\) 次操做後 \(b\) 的指望(原題是求全部方案的 \(b\) 之和,本質同樣……)。code

\(1\le n,m,Q\le2\times 10^5\)ci


# 解析

這是一道利用指望線性性分拆貢獻的好題:),具體分拆貢獻分爲兩步:get

(Ⅰ)將 \(\mathbf{E(b)}\) 分拆爲每一次操做對 \(\mathbf b\) 的貢獻。string

由題意易知只有 C操做 會對 \(b\) 有貢獻。若第 \(i\) 次操做是 C 操做,設其對 \(b\) 的貢獻爲 \(ans_i\)。一共有 \((2m+1)\binom n2\) 種操做,而 C 操做有 \(\binom n2\) 種,因而某一次操做是 C 操做的機率是 \(\frac 1{2m+1}\)。而後能夠寫出下面的式子:it

\[E(b)=\sum_{j=1}^Q\frac1{2m+1}E(ans_j) \]

考慮怎麼計算 \(E(ans_j)\)io

Tab.\(a_{i,j}\) 表示數字 \(a_i\)\(j\) 次操做後的值。class

(Ⅱ)將 \(\mathbf{E(ans_j)}\) 分拆爲每一個 \(\mathbf{E(a_{i,j})}\) 的貢獻。技巧

某次操做區間包含 \(a_i\) 的機率爲 \(\frac{i(n-i+1)}{\binom n2}\),則

\[E(ans_j)=\sum_{i=1}^n\frac{i(n-i+1)}{\binom n2}E(a_{i,j}) \]

而對於 \(E(a_{i,j})\),要利用到將離散指望用機率表達的技巧:

\[E(a_{i,j})=\sum_{k=0}^{m-1}P(a_{i,j}>k) \]

爲了方便計算上式的機率,咱們定義一次操做對 \(a_i\) 有效,當且僅當:

  • 是 A/B 操做;
  • 操做區間包含 \(i\)
  • 若是是 A(max) 操做,則要求 \(v\ge a_i\);若是是 B(min) 操做,則要求 \(v< a_i\)

那麼能夠推得某一次操做對 \(a_i\) 有效的機率爲 \(H_i=\frac{i(n-i+1)}{\binom n2}\cdot\frac{2m}{2m+1}\cdot\frac{a_i+(m-a_i-1)}{m}\),發現機率與 \(a_i\) 無關。

那麼何時會有 \(a_{i,j}>k\)?當且僅當最後一次有效操做\(v\)\(v>k\)。因此 \(P(a_{i,j}>k)\) 能夠這樣計算:

  • 在前 \((j-1)\) 次操做中(第 \(j\) 次是 C 操做,必定無效)存在有效操做:\([1-(1-H_i)^{j-1}]\)(即從全部方案中減去 \(j-1\) 次操做都無效的方案);
  • 最後一次有效操做 \(v>k\)\(\frac{m-k-1}m\)

因此 \(P(a_{i,j}>k)=\frac{m-k-1}m[1-(1-H_i)^{j-1}]\)

綜上

\[\begin{aligned} E(a_{i,j})&=\sum_{k=0}^{m-1}\tfrac{m-k-1}m\cdot[1-(1-H_i)^{j-1}]\\ &=[1-(1-H_i)^{j-1}]\cdot\tfrac{m-1}2\\ E(ans_j)&=\sum_{i=1}^n\tfrac{i(n-i+1)}{\tbinom n2}\cdot[1-(1-H_i)^{j-1}]\cdot\tfrac{m-1}2 \end{aligned} \]

最後

\[\begin{aligned} E(b)&=\sum_{j=1}^Q\sum_{i=1}^n\tfrac{i(n-i+1)}{\tbinom n2}\cdot[1-(1-H_i)^{j-1}]\cdot\tfrac{m-1}2\\ &=\frac{m-1}2\cdot\sum_{i=1}^n\tfrac{i(n-i+1)}{\tbinom n2}\sum_{j=1}^Q\cdot[1-(1-H_i)^{j-1}] \end{aligned} \]

後面對 \(1-(1-H_i)^{j-1}\) 的式子求和就用等比數列,能夠作到 \(O(\log Q)\),因而總複雜度 \(O(n\log Q)\)


# 源代碼

/*Lucky_Glass*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int MOD=998244353;
#define ci const int &

inline int Add(ci a,ci b){return a+b>=MOD? a+b-MOD:a+b;}
inline int Sub(ci a,ci b){return a-b<0? a-b+MOD:a-b;}
inline int Mul(ci a,ci b){return 1ll*a*b%MOD;}
inline int Pow(ci a,ci b){return b? Mul(Pow(Mul(a,a),b>>1),(b&1)? a:1):1;}

int n,m,Q;

//p^0+p^1+...+p^(t-1)
int loca(int varp,int vart){return Mul(Sub(Pow(varp,vart),1),Pow(Sub(varp,1),MOD-2));}
int main(){
    scanf("%d%d%d",&n,&m,&Q);
    int var1=Pow(Mul(n,n+1),MOD-2),var2=Pow(2*m+1,MOD-2),var3=Mul(Sub(m,1),Pow(2,MOD-2)),ans=0;
    for(int i=1;i<=n;i++){
        int varq=Mul(Mul(i,n-i+1),Mul(var1,var2)),varp=Mul(Mul(Mul(m,i),n-i+1),Mul(var1,var2));
        varp=Mul(varp,2),varq=Mul(varq,2);
        int sum=Sub(Q,loca(Sub(1,varp),Q));
        ans=Add(ans,Mul(sum,Mul(var3,varq)));
    }
    int all=Pow(Mul(Mul(n,n+1),Mul(Pow(2,MOD-2),2*m+1)),Q);
    // printf("? %d\n",all);
    printf("%d\n",Mul(ans,all));
    return 0;
}

THE END

Thanks for reading!

\[\begin{split} 「\ &未料想在你手中\ 最過珍惜的三尺青鋒\\ &會在某一日\ 爲某一我的\\ &縱起破長空\ 作了一世真英雄\ 」\\ ——&\text{《何日重到蘇瀾橋》By 泠鳶yousa} \end{split} \]

Linked 何日重到蘇瀾橋-Bilibili

相關文章
相關標籤/搜索