[HNOI2010 Bounce]

[关键字]:块状链表

[题目大意]:有n个弹力装置,绵羊落在i个装置上会被向后弹到i+ki个装置上或被弹飞,问从i个装置开始要想被弹飞需要多少次,中间会改变装置的弹力系数。

//=============================================================================================

[分析]:做法有三种:动态树(不会)、伸展树+括号序列(不会+太麻烦)、块状链表。虽然块状链表在这里只是水过,但还是很好写和理解的。在以sqrt(n)分块后,对每个装置维护f[i].t[i],

f[i]表示从i开始要弹几次才能弹出该块,可以用递推来维护,t[i]表示i会弹到下一个块的哪个装置上。查找时只要沿着t[]数组找到头累加f[]值就行了。更改时因为只会往后弹,所以只要将与要修改装置在同一个块里且在他后面的装置的f[]\t[]再算一遍就行了。

[代码]:

View Code
#include<iostream>

#include<cstdio>

#include<cstdlib>

#include<cstring>

#include<algorithm>

#include<cmath>

using namespace std;



const int MAXN=1000;



int n,m,tot;

int belong[MAXN],l[MAXN],f[MAXN],t[MAXN],k[MAXN];



void Init()

{

    scanf("%d",&n);

    int m=(int)sqrt(n),j=m;

    //printf("%d\n",m);

    for (int i=0;i<n;++i)

    {

        scanf("%d",&k[i]);

        if (j==m) j=1,l[++tot]=i;

        else ++j;

        belong[i]=tot;

    }

    l[tot+1]=n;

    for (int i=n-1;i>=0;--i)

        if (i+k[i]>=l[belong[i]+1]) f[i]=1,t[i]=i+k[i];

           else f[i]=f[i+k[i]]+1,t[i]=t[i+k[i]];

}



int ask(int pos)

{

    int sum=0;

    while (pos<n) {sum+=f[pos],pos=t[pos];}

    //printf("\n");

    return sum;

}



void Change(int j,int k2)

{

     k[j]=k2;

     for (int i=j;i>=l[belong[j]];--i)

         if (i+k[i]>=l[belong[i]+1]) f[i]=1,t[i]=i+k[i];

            else f[i]=f[i+k[i]]+1,t[i]=t[i+k[i]];

}



void Solve()

{

     scanf("%d",&m);

     int flag,j,k2;

     while (m--)

     {

           scanf("%d",&flag);

           if (flag==1)

           {

                       scanf("%d",&j);

                       printf("%d\n",ask(j));

           }

           if (flag==2)

           {

                       scanf("%d%d",&j,&k2);

                       Change(j,k2);

           }

     }

}



int main()

{

    freopen("in.txt","r",stdin);

    freopen("out.txt","w",stdout);

    Init();

    /*for (int i=0;i<n;++i)

        printf("%d %d %d\n",belong[i],f[i],t[i]);*/

    Solve();

    fclose(stdin);

    fclose(stdout);

    return 0;

}

你可能感兴趣的:(BO)