同bzoj2002 弹飞绵羊(改了改2002也水过去了)
基本思想还是,均衡修改和询问的复杂度,降到n sqrt n的
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int N=200005;
int n,m,block;
int end[N],pos[N],cnt[N],next[N],a[N];
void updata(int i,int t)
{
if (t>n) {cnt[i]=1;next[i]=-1;end[i]=i;}
else
{
if (pos[i]==pos[t]) {next[i]=next[t];cnt[i]=cnt[t]+1;end[i]=end[t];}
else {next[i]=t;cnt[i]=1;end[i]=end[t];}
}
}
int query(int x)
{
int ans=0,f;
for (;x!=-1;x=next[x])
{
ans+=cnt[x];
f=end[x];
}
printf("%d %d\n",f,ans);
}
int main()
{
scanf("%d%d",&n,&m);
int block=sqrt(1.0*n);
for (int i=1;i<=n;i++) pos[i]=(i-1)/block+1;
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=n;i>=1;i--) updata(i,i+a[i]);
int opt,x,y;
while (m--)
{
scanf("%d",&opt);
if (opt==1)
{
scanf("%d",&x);
query(x);
}
else
{
scanf("%d%d",&x,&y);
a[x]=y;
int r=min(n,pos[x]*block),l=(pos[x]-1)*block+1;
for (int i=r;i>=l;i--) updata(i,i+a[i]);
}
}
return 0;
}