bzoj2002 分块
某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
据说可以用动态树做,可是我不会
又说可以用分块做。
事实上如果只询问1次的话,可以O(n)处理,O(1)输出
如果只修改一次的话,可以O(n)输出,O(1)处理
所以如果我们进行分块,就可以做到修改只对当前块进行修改,输出以块为整体进行输出。
时间复杂度O(n√n)
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; inline int read(){int now=0;register char c=getchar();for(;!isdigit(c);c=getchar()); for(;isdigit(c);now=now*10+c-'0',c=getchar());return now;} #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x); #define Pri(x) printf("%d\n", x) #define Prl(x) printf("%lld\n",x); #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; const double eps = 1e-9; const int maxn = 2e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int a[maxn]; int to[maxn],step[maxn]; int size; inline int query(int x){ int ans = 0; while(~x){ ans += step[x]; x = to[x]; } return ans; } inline void update(int x,int y){ int s = x / size * size,t = (x / size + 1) * size - 1; a[x] = y; for(int i = x; i >= s; i --){ if(i + a[i] >= N){ to[i] = -1; step[i] = 1; }else if(i + a[i] > t){ to[i] = i + a[i]; step[i] = 1; }else{ to[i] = to[i + a[i]]; step[i] = step[i + a[i]] + 1; } } } int main() { Sca(N); size = sqrt(N); For(i,0,N - 1) Sca(a[i]); for(int i = N - 1;i >= 0 ; i --){ int t = (i / size + 1) * size - 1; if(i + a[i] >= N){ to[i] = -1; step[i] = 1; }else if(i + a[i] > t){ to[i] = i + a[i]; step[i] = 1; }else{ to[i] = to[i + a[i]]; step[i] = step[i + a[i]] + 1; } } Sca(M); while(M--){ int op,x,y; Sca(op); if(op == 1){ Sca(x); Pri(query(x)); }else{ Sca2(x,y); update(x,y); } } #ifdef VSCode system("pause"); #endif return 0; }