CF797E Array Queries

一个根号分块经典题。
考虑如果我们直接\(dp\)求的话是\(O(n * n)\)
我们发现这个dp的复杂度有一维是值域大小。
我们还发现我们其实没有必要把所有的答案都求出来,如果\(\sqrt n \leq k\),那么最多不会超过\(\sqrt n\)步,我们完全可以进行暴力。
于是我们只需要处理\(k \leq \sqrt n\)的部分,dp的复杂度也变成\(O(n\sqrt n)\)

CF797E Array Queries
#include<iostream>
#include<cstdio>
#include<cmath>
#define ll long long
#define N 100005
#define B 333

int p[N][B],a[N],n,m;

int main(){
   scanf("%d",&n);
   for(int i = 1;i <= n;++i)
   scanf("%d",&a[i]);
   ll b = std::sqrt(n);
   for(int i = n;i >= 1;--i)
   for(int j = 1;j <= b;++j){
   	p[i][j] = ((i + j + a[i]) > n) ? 1 : (p[i + j + a[i]][j] + 1);
   }
   scanf("%d",&m);
   while(m -- ){
   	ll x,y;
   	scanf("%lld%lld",&x,&y);
   	if(y <= b)
   	std::cout<<p[x][y]<<std::endl;
   	else{
   		int cnt = 0;
   		while(x <= n)
   		x = x + y + a[x],cnt ++ ;
   		std::cout<<cnt<<std::endl;
   	}
   }
} 
posted @ 2021-05-12 20:39  fhq_treap  阅读(67)  评论(0编辑  收藏  举报