Educational Codeforces Round 19 E. Array Queries

来源:互联网 发布:雷迪克数据 编辑:程序博客网 时间:2024/05/17 23:12

题意

给出n个数,q个询问,每个询问有两个数p,k,询问p+k+a[p]操作几次后超过n

分析

分块处理,在k<sqrt(n)时,用dp,大于sqrt(n)用暴力

状态:dp[i][j]表示对j进行操作,每次加上a[i]+j(同时更新i的值),最后使i>n所需的操作次数。

     ┏ dp[i+a[i]+j][j]+1 , i+a[i]+j<=n;

dp[i][j]=┃

     ┗  1  ,  i+a[i]+j>n.


#include <bits/stdc++.h>//#include <ext/pb_ds/tree_policy.hpp>//#include <ext/pb_ds/assoc_container.hpp>//using namespace __gnu_pbds;using namespace std;#define pi acos(-1)#define endl '\n'#define me(x) memset(x,0,sizeof(x));#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)#define close() ios::sync_with_stdio(0);typedef long long LL;const int INF=0x3f3f3f3f;const LL LINF=0x3f3f3f3f3f3f3f3fLL;const int dx[]={-1,0,1,0,-1,-1,1,1};const int dy[]={0,1,0,-1,1,-1,1,-1};const int maxn=1e3+5;const int maxx=1e5+100;const double EPS=1e-7;const int MOD=1000000007;#define mod(x) ((x)%MOD);template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}//typedef tree<pt,null_type,less< pt >,rb_tree_tag,tree_order_statistics_node_update> rbtree;/*lch[root] = build(L1,p-1,L2+1,L2+cnt);    rch[root] = build(p+1,R1,L2+cnt+1,R2);中前*//*lch[root] = build(L1,p-1,L2,L2+cnt-1);    rch[root] = build(p+1,R1,L2+cnt,R2-1);中后*/long long gcd(long long a , long long b){if(b==0) return a;a%=b;return gcd(b,a);}inline int Scan(){    int res=0,ch,flag=0;    if((ch=getchar())=='-')flag=1;    else if(ch>='0' && ch<='9')res=ch-'0';    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0';    return flag ? -res : res;}int dp[maxx][350];int a[maxx];int main(){    int n;    n=Scan();    for(int i=1;i<=n;i++)        a[i]=Scan();    for(int i=n;i;i--)        for(int j=1;j<350;j++)        {            if(i+j+a[i]>n) dp[i][j]=1;            else dp[i][j]=dp[i+a[i]+j][j]+1;        }    int q;    q=Scan();    while(q--)    {        int p,k;        p=Scan();k=Scan();        if(k<350)        {            cout<<dp[p][k]<<endl;            continue;        }        int ans=1;        while((p=p+k+a[p])<=n) ans++;        cout<<ans<<endl;    }}



0 0