CF797E Array Queries

一个根号分块经典题。
考虑如果我们直接(dp)求的话是(O(n * n))
我们发现这个dp的复杂度有一维是值域大小。
我们还发现我们其实没有必要把所有的答案都求出来,如果(sqrt n leq k),那么最多不会超过(sqrt n)步,我们完全可以进行暴力。
于是我们只需要处理(k leq sqrt n)的部分,dp的复杂度也变成(O(nsqrt 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;
   	}
   }
} 
原文地址:https://www.cnblogs.com/dixiao/p/14761620.html