CF797E Array Queries 題解
阿新 • • 發佈:2022-05-20
題意:
給定一個序列 \(a\),給定 \(T\) 組 \(p, k\),每次操作為 \(p = p + a_p + k\),問需要操作幾次才能使得 \(p > n\)。
思路:
模擬的時間複雜度為 \(\mathcal{O}(\frac{n}{k})\),如果全部資料按照模擬會超時。
我們設 \(dp_{i,j}\) 當 $p = i, k = j $ 時的答案,空間複雜度為 \(O(nk)\),會炸。
我們考慮將兩種做法結合起來。
如果 \(k = \sqrt n\) 的時候,操作次數為 \(\sqrt n\)。當 \(k > \sqrt n\) 的時候,答案必定會小於 \(\sqrt n\)
對於 \(k < \sqrt n\) 的這部分答案來說,我們可以用第二種辦法提前預處理出來,詢問時直接輸出即可。
Ac code:
\[The\ End. \]int dp[maxn >> 1][350], num, a[N]; signed main() { int tests = 1; //tests = read(); while(tests--) { int n = read(); num = sqrt(n); for(int i = 1; i <= n; i++) a[i] = read(); int T = read(); for(int i = n; i >= 1; i--) { for(int j = 1; j <= num; j++) { if(a[i] + i + j > n) dp[i][j] = 1; else dp[i][j] = dp[i + a[i] + j][j] + 1; } } while(T--) { int p = read(), k = read(); if(k <= num) printf("%d\n", dp[p][k]); else { int js = 0; while(p <= n) { js++, p = p + a[p] + k; } printf("%d\n", js); } } } }