今天原来打算做ZOJ月赛的,等到中午的时候感觉太困了,就睡了一觉,然后就没有然后了。。。
这题正版写法应该是LCT,但是分块也能过,而且写起来特别简单,LCT写的话应该是一个Cut,Link操作,维护的就是答案的值(没写)。
下面附上代码:
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #define LL long long #define FOR(i,x,y) for(int i = x;i < y;i ++) #define IFOR(i,x,y) for(int i = x;i > y;i --) #define MAXN 220000 using namespace std; int n,m,ct[MAXN],nt[MAXN],val[MAXN]; int blocks; void Modify(int u,int v){ nt[u] = v; ct[u] = 1; if(v >= n) return; if(u/blocks == v/blocks){ ct[u] += ct[v]; nt[u] = nt[v]; } } int Query(int x){ int ans = 0; while(x < n){ ans += ct[x]; x = nt[x]; } return ans; } int main() { //freopen("test.in","r",stdin); while(~scanf("%d",&n)){ FOR(i,0,n) scanf("%d",&val[i]); blocks = (int)sqrt(n+0.5) + 1; IFOR(i,n-1,-1){ Modify(i,i+val[i]); } scanf("%d",&m); FOR(i,0,m){ int op; scanf("%d",&op); if(op == 1){ int x; scanf("%d",&x); printf("%d ",Query(x)); } else{ int x,w; scanf("%d%d",&x,&w); val[x] = w; int u = x/blocks*blocks; IFOR(i,x,u-1){ Modify(i,i + val[i]); } } } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。