您的位置:首页 > 其它

BZOJ2002(Hnoi2010)[Bounce 弹飞绵羊]--分块

2017-10-14 08:29 405 查看
【链接】

bzoj2002

【解题报告】

听说这是裸LCT啊,不会啊,只能用分块大法了,我太弱了QAQ

看题目n挺小的,直接分块大法就好了。

#include<cstdio>
#include<cmath>
#define Block(x) ((x)-1)/S+1
#define min(x,y) ((x)<(y))?(x):(y)
using namespace std;
const int maxn=200005;
int n,m,S,a[maxn],nxt[maxn],p[maxn];
inline char nc()
{
static char buf[100000],*l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
if (l==r) return EOF; return *l++;
}
inline int Read()
{
int res=0; char ch=nc();
while (ch<'0'||ch>'9') ch=nc();
while (ch>='0'&&ch<='9') res=(res<<3)+(res<<1)+ch-48,ch=nc();
return res;
}
void Updata(int x)
{
int s=Block(x),t=Block(x+a[x]);
if (t>s||x+a[x]>n) nxt[x]=min(x+a[x],n+1),p[x]=1;
else nxt[x]=nxt[x+a[x]],p[x]=p[x+a[x]]+1;
}
int Query(int x) {int sum=0; while (x<=n) sum+=p[x],x=nxt[x]; return sum;}
int main()
{
freopen("2002.in","r",stdin);
freopen("2002.out","w",stdout);
n=Read(); S=sqrt(n);
for (int i=1; i<=n; i++) a[i]=Read();
for (int i=n; i; i--) Updata(i);
m=Read();
for (int i=1; i<=m; i++)
{
int z=Read(),x=Read()+1;
if (z==1) printf("%d\n",Query(x));
else{a[x]=Read(); for (int i=x,s=(Block(x)-1)*S+1; i>=s; i--) Updata(i);}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: