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;
}

浙公网安备 33010602011771号