BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊(分块)
http://www.lydsy.com/JudgeOnline/problem.php?id=2002
题意
思路
不会LCT,就只好用分块了。
将这n个数分成根号n块,对于每一块中的每一个数,处理出它跳出它所在块的下一个位置和所需跳数。
这样如果要修改x的话,我们只需要修改一个x所在的块即可。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> #include<stack> #include<queue> #include<cmath> #include<map> #include<set> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int INF = 0x3f3f3f3f; const int maxn = 200000+5; int n, m; int a[maxn],pos[maxn],jump[maxn]; int main() { //freopen("in.txt","r",stdin); scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); int block = sqrt(n+0.5); for(int i=n-1;i>=0;i--) { int tmp = i+a[i]; if(tmp>=n) {pos[i]=-1;jump[i]=1;} else if(tmp>=(i/block+1)*block) {pos[i]=tmp;jump[i]=1;} else {pos[i]=pos[tmp];jump[i]=jump[tmp]+1;} } scanf("%d",&m); while(m--) { int x,y; int op; scanf("%d",&op); if(op==1) { int ans = 0; scanf("%d",&x); for(int i=x;i!=-1;i=pos[i]) ans+=jump[i]; printf("%d\n",ans); } else { scanf("%d%d",&x,&y); a[x]=y; for(int i=x;i>=x/block*block;i--) { int tmp = i+a[i]; if(tmp>=n) {pos[i]=-1;jump[i]=1;} else if(tmp>=(i/block+1)*block) {pos[i]=tmp;jump[i]=1;} else {pos[i]=pos[tmp];jump[i]=jump[tmp]+1;} } } } return 0; }