zoukankan      html  css  js  c++  java
  • bzoj2002 [Hnoi2010]Bounce 弹飞绵羊

    某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。

    Input

    第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1,接下来一行有n个正整数,依次为那n个装置的初始弹力系数。第三行有一个正整数m,接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000

    Output

    对于每个i=1的情况,你都要输出一个需要的步数,占一行。

    Sample Input

    4 
    1 2 1 1 
    3
    1 1
    2 1 1
    1 1

    Sample Output

    2
    3

    这道题感触颇深,因为听了许多次,但是都不是特别理解,现在终于
    懂了。

    题解:预处理出当前这个点,跳到下一个块什么位置,需要跳几次,
    普通跳的话就从当前这个位置开始跳,修改只将影响这个块的进行
    修改。
     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<iostream>
     5 #include<cstring>
     6 #define N 200007
     7 using namespace std;
     8 
     9 int n,m;
    10 int blk,cnt;
    11 int p[N],st[N],k[N],belong[N],l[N],r[N];
    12 
    13 int cal(int x)
    14 {
    15     int res=0;
    16     while(1)
    17     {
    18         res+=st[x];
    19         if (p[x]==0) break;
    20         x=p[x];
    21     }
    22     return res;
    23 }
    24 int main()
    25 {
    26     scanf("%d",&n);blk=sqrt(n);
    27     for (int i=1;i<=n;i++)
    28         scanf("%d",&k[i]);
    29     if (n%blk==0) cnt=n/blk+1;
    30     else cnt=n/blk;
    31     for (int i=1;i<=cnt;i++)
    32         l[i]=(i-1)*blk+1,r[i]=i*blk;
    33     r[cnt]=n;
    34     for (int i=1;i<=n;i++)
    35         belong[i]=(i-1)/blk+1;
    36     for (int i=n;i>=1;i--)
    37     {
    38         if (i+k[i]>n) st[i]=1;
    39         else if (belong[i]==belong[i+k[i]]) st[i]=st[i+k[i]]+1,p[i]=p[i+k[i]];
    40         else st[i]=1,p[i]=i+k[i];
    41     }
    42     scanf("%d",&m);
    43     for (int i=1;i<=m;i++)
    44     {
    45         int t,x,y;
    46         scanf("%d%d",&t,&x);
    47         if (t==2) scanf("%d",&y);
    48         x++;
    49         if (t==1) printf("%d
    ",cal(x));
    50         else
    51         {
    52             k[x]=y;
    53             for (int i=x;i>=l[belong[x]];i--)
    54                 if (belong[i]==belong[i+k[i]]) st[i]=st[i+k[i]]+1,p[i]=p[i+k[i]];
    55                 else st[i]=1,p[i]=i+k[i];
    56         }
    57     }    
    58 }
     
  • 相关阅读:
    LeetCode 45 Jump Game II
    LeetCode 54. Spiral Matrix
    LeetCode 53. Maximum Subarray
    LeetCode 52. N-Queens II
    智齿的秘密
    《婚姻故事》观影笔记
    为什么在linux系统下安装anaconda的时候会报错
    pandas时间序列学习笔记
    极大似然估计和最小二乘法
    粗糙集学习笔记
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7588500.html
Copyright © 2011-2022 走看看