zoukankan      html  css  js  c++  java
  • 洛谷 P3203 BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊

    题目描述

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

    输入输出格式

    输入格式:

    第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1。

    接下来一行有n个正整数,依次为那n个装置的初始弹力系数。

    第三行有一个正整数m,

    接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    4
    1 2 1 1
    3
    1 1
    2 1 1
    1 1
    输出样例#1: 复制
    2
    3

    说明

    对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000

    解题思路

      LCT不会,或者分块。

      分成$sqrt{n}$块,对于每个格子,维护三个值——$a[i]$第$i$个点的弹力系数,即弹射距离;$nxtn[i]$,弹射到下一个块所需的步数;$nxtp[i]$,从第i个点开始跳,直到离开这个块时的下一个位置(便于统计是一个块一个块地跳)。

      输入数据后,从后向前递推求出$nxtp[i]$和$nxtn[i]$。

      询问从$x$点开始,要弹飞所需的步数,就从$x$开始,利用$nxtp[i]$暴力跳块,用$nxtn[i]$暴力统计答案,直到飞了,输出答案。

      修改第$x$个点的弹力系数,就先把$a[x]$的值修改了,然后从后往前暴力递推$x$所在块的$nxtp[i]$和$nxtn[i]$。

    源代码

     1 #include<stdio.h>
     2 #include<math.h>
     3 
     4 int n,t,m;
     5 int a[200010]/*弹力*/,nxtp[200010]/*到下一块的位置*/,nxtn[200010]/*到下一块的步数*/;
     6 
     7 
     8 int main()
     9 {
    10     //freopen("test.in","r",stdin);
    11     scanf("%d",&n);
    12     t=sqrt(n);//块数
    13     for(int i=0;i<n;i++)
    14     {
    15         scanf("%d",a+i);
    16     }
    17     for(int i=n-1;i>=0;i--)//i/t获得块数
    18     {
    19         if(i+a[i]>=n) nxtp[i]=n,nxtn[i]=1;
    20         else if(i/t!=(i+a[i])/t) nxtp[i]=i+a[i],nxtn[i]=1;
    21         else nxtp[i]=nxtp[i+a[i]],nxtn[i]=1+nxtn[i+a[i]];
    22     }
    23     scanf("%d",&m);
    24     while(m--)
    25     {
    26         int opt;
    27         scanf("%d",&opt);
    28         if(opt==1)
    29         {
    30             int x;
    31             scanf("%d",&x);
    32             int ans=0;
    33             while(x<n)
    34             {
    35                 ans+=nxtn[x];
    36                 x=nxtp[x];
    37             }
    38             printf("%d
    ",ans);
    39         }
    40         else
    41         {
    42             int x,y;
    43             scanf("%d%d",&x,&y);
    44             a[x]=y;
    45             for(int i=(x/t+1)*t;i>=x/t*t;i--)
    46             {
    47                 if (i + a[i] >= n)
    48                     nxtp[i] = n, nxtn[i] = 1;
    49                 else if (i / t != (i + a[i]) / t)
    50                     nxtp[i] = i + a[i], nxtn[i] = 1;
    51                 else
    52                     nxtp[i] = nxtp[i + a[i]], nxtn[i] = 1 + nxtn[i + a[i]];
    53             }
    54         }
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    七牛图片上传JSSDK
    2015年12月中国航空公司名录
    HTML5 开发框架
    利用HTML5定位功能,实现在百度地图上定位
    openerp7 时区问题
    AS3使用Json 传复杂数据 -------- 用数组而不是向量
    随便写写
    生产环境该如何选择lvs的工作模式,和哪一种算法
    获取Linux权限后安装rootkit
    IT求职经验分享
  • 原文地址:https://www.cnblogs.com/wawcac-blog/p/10586091.html
Copyright © 2011-2022 走看看