您的位置:首页 > 其它

BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊

2018-04-04 11:11 429 查看

题目链接

https://www.lydsy.com/JudgeOnline/problem.php?id=2002

思路

分块,维护块内一个点在块中跳的步数以及出了这个块后去了哪个点。

暴力维护时,注意要用后面节点跳到的位置,来优化寻找前面节点跳到的位置的过程。

代码

#include <cstdio>
#include <cmath>
#include <algorithm>

const int maxn=200000;

int belong[maxn+10],cnt[maxn+10],to[maxn+10],n,m,ki[maxn+10],size;

int main()
{
scanf("%d",&n);
for(register int i=0; i<n; ++i)
{
scanf("%d",&ki[i]);
}
size=(int)sqrt(n);
for(register int i=0; i<n; ++i)
{
belong[i]=i/size+1;
}
for(register int i=n-1; i>=0; --i)
{
if(i+ki[i]>=n)
{
to[i]=-1;
cnt[i]=1;
}
else if(belong[i+ki[i]]!=belong[i])
{
to[i]=i+ki[i];
cnt[i]=1;
}
else
{
to[i]=to[i+ki[i]];
cnt[i]=cnt[i+ki[i]]+1;
}
}
scanf("%d",&m);
while(m--)
{
int op,a,b;
scanf("%d",&op);
if(op==1)
{
scanf("%d",&a);
int ans=0;
while(a!=-1)
{
ans+=cnt[a];
a=to[a];
}
printf("%d\n",ans);
}
else
{
scanf("%d%d",&a,&b);
ki[a]=b;
for(register int i=a; i>=(belong[a]-1)*size; --i)
{
if(i+ki[i]>=n)
{
to[i]=-1;
cnt[i]=1;
}
else if(belong[i+ki[i]]!=belong[i])
{
to[i]=i+ki[i];
cnt[i]=1;
}
else
{
to[i]=to[i+ki[i]];
cnt[i]=cnt[i+ki[i]]+1;
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: