codeforces 797 E Array Queries

来源:互联网 发布:土木工程设计软件 编辑:程序博客网 时间:2024/06/05 09:07

E. Array Queries
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

a is an array of n positive integers, all of which are not greater than n.

You have to process q queries to this array. Each query is represented by two numbers p and k. Several operations are performed in each query; each operation changes p to p + ap + k. There operations are applied until p becomes greater than n. The answer to the query is the number of performed operations.

Input

The first line contains one integer n (1 ≤ n ≤ 100000).

The second line contains n integers — elements of a (1 ≤ ai ≤ n for each i from 1 to n).

The third line containts one integer q (1 ≤ q ≤ 100000).

Then q lines follow. Each line contains the values of p and k for corresponding query (1 ≤ p, k ≤ n).

Output

Print q integers, ith integer must be equal to the answer to ith query.

Example
input
31 1 131 12 13 1
output
211
Note

Consider first example:

In first query after first operation p = 3, after second operation p = 5.

In next two queries p is greater than n after the first operation.


本题的入手点在于分别考虑解决问题的难点,以及巧妙地暴力。

  • 在不考虑 n 的数据规模的情况下,可以根据每个查询暴力解出答案(用变量的变化模拟 p 的移动)。
  • 在不考虑 k 的数据规模的情况下,可以进行动态规划。令 d[i][j] 表示当前起始位置为 i , k 为 j 的情况下需要多少步能够走出数组,那么按照 i 从大到小的顺序 DP 就能得到答案 d[p][k] 。

但是本题的问题在于 n 和 k 的数据规模必须同时被考虑。在这种情况下,当 k 比较小的时候(比如小于 100 的时候)我们可以动态规划,当 k 比较大的时候,我们可以暴力。

毕格斯茅问题


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 1e5 + 5;int dp[maxn][505], a[maxn], n, p, q, k;int calc(int p, int k){    int cnt = 0;    while(p <= n)    {        cnt++;        p = p + a[p] + k;    }    return cnt;}int main(){    scanf("%d", &n);    for(int i = 1; i <= n; i++)        scanf("%d", &a[i]);    for(int i = n; i >= 1; i--)        for(int j = 1; j <= 500; j++)        {            if(i+a[i]+j > n) dp[i][j] = 1;            else dp[i][j] = dp[i+a[i]+j][j]+1;        }    scanf("%d", &q);    while(q--)    {        scanf("%d%d", &p, &k);        if(k <= 500)            printf("%d\n", dp[p][k]);        else            printf("%d\n", calc(p, k));    }    return 0;}


0 0