1. 程式人生 > 其它 >cf621 E. Wet Shark and Blocks

cf621 E. Wet Shark and Blocks

題意:

長為 n 的陣列,元素都是 \(1\sim 9\) 的整數。每次從陣列中有放回地取數,取 b 次,把取出來的陣列成一個大整數。問使得這個大整數 \(\%x=k\) 的方案數。

\(1\le a_i\le 9,2\le n\le 5e4, 1\le b\le 1e9,0\le k<x,2\le x\le 100\)

思路:

\(dp(i,j)\) 表示取了 \(i\) 位數,湊出來的和模 x 為 \(j\) 的方案數。則 \(dp(i+1,(10j+a_{1\sim n})\%x)+=dp(i,j)\)

矩陣快速冪優化,行向量的第 \(j\) 個元素 \(B(j)\) 表示湊出 \(j\)

的方案數,\(0\le j < x\)

\[\begin{pmatrix} B_0 & B_1 & \cdots & B_{x-1} \end{pmatrix} \begin{pmatrix} \cdots & A_{0,j} & \cdots \\ \cdots & A_{1,j} & \cdots \\ & \vdots & \\ \cdots & A_{x-1,j} & \cdots \end{pmatrix} = \begin{pmatrix} \cdots & B'_{j} & \cdots \end{pmatrix} \]

怎麼構造 \(A\)

呢?要讓新的 \(B_j' = \sum\limits _{ (10i+v)\%x=j } B_i\),只需對陣列中的每個數 \(v\),把 \(A[i][j=(10i+v)\%x]\) 加上1

注意到一開始 \(B=(1,0,0,\cdots)\),所以答案是 \(A[0][k]\)

cin >> n >> b >> k >> x;
for(int i = 1; i <= n; i++) {
    ll v; cin >> v;
    for(int j = 0; j < x; j++)
        ++A[j][(j*10+v)%x];
}

qmi(A, b);
cout << A[0][k];