【分析1】分塊—分段,詳見鄒逍遙《淺談分塊在一類在線問題中的應用》的第一道
【代碼1】分段/**************************************************************
Problem: 2002
User: y20070316
Language: C++
Result: Accepted
Time:5236 ms
Memory:4212 kb
****************************************************************/
#include <bits/stdc++.h>
using namespace std;
const int N=200010;
const int BLOCK_SIZE=500;
const int BLOCK_NUMBER=500;
int n,m,unit;
struct Block
{
int w[BLOCK_NUMBER];
int len[BLOCK_NUMBER];
int anc[BLOCK_NUMBER];
}ud_list[BLOCK_SIZE];
inline int Read(void)
{
int s=0,f=1; char c=getchar();
for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
for (;isdigit(c);c=getchar()) s=s*10+c-'0';
return s*f;
}
void Caculate(int nowBlock)
{
int preCnt=(nowBlock-1)*unit,r=min(unit,n-(nowBlock-1)*unit);
for (int i=r;i>=1;i--)
if (i+ud_list[nowBlock].w[i]<=r)
{
ud_list[nowBlock].anc[i]=ud_list[nowBlock].anc[i+ud_list[nowBlock].w[i]];
ud_list[nowBlock].len[i]=ud_list[nowBlock].len[i+ud_list[nowBlock].w[i]]+1;
}
else
{
ud_list[nowBlock].anc[i]=i;
ud_list[nowBlock].len[i]=1;
}
}
inline void Find(int x,int &nowBlock,int &nowPos)
{
if (x>n)
{
nowBlock=n+1;
nowPos=n+1;
}
else
{
nowBlock=(x-1)/unit+1;
nowPos=x-(nowBlock-1)*unit;
}
}
int Query(int x)
{
int nowBlock,nowPos,sumLen=0;
Find(x,nowBlock,nowPos);
for (;nowBlock!=n+1&&nowPos!=n+1;)
{
sumLen+=ud_list[nowBlock].len[nowPos];
Find((nowBlock-1)*unit+ud_list[nowBlock].anc[nowPos]+ud_list[nowBlock].w[ud_list[nowBlock].anc[nowPos]],nowBlock,nowPos);
}
return sumLen;
}
int main(void)
{
int nowBlock=0,nowPos;
n=Read();
unit=sqrt(n);
for (int i=1;i<=n;i++)
{
if (i%unit==1) nowBlock++,nowPos=0;
ud_list[nowBlock].w[++nowPos]=Read();
}
for (int i=1;(i-1)*unit<n;i++) Caculate(i);
int k,x;
m=Read();
for (int i=1;i<=m;i++)
{
k=Read(),x=Read()+1;
if (k==1)
printf("%d\n",Query(x));
else
{
Find(x,nowBlock,nowPos);
ud_list[nowBlock].w[nowPos]=Read();
Caculate(nowBlock);
}
}
return 0;
}