某天,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 Input4 1 2 1 1 31 12 1 11 1

Sample Output23


题解:这是一个分块的问题;我们可以将其分成sqrt(n)块,如果有剩余,使num+=1;然后分别记录从当前块到下一个快所需的步数nxt[i]以及跳到下一个快的位置id[i],如果一步不能到达下一个块 nxt[i]=nxt[i+a[i]]+1,id[i]=id[i+a[i]];(注: a[i]为第i 个弹跳的幅度),若能,nxt[i]=1,id[i]=i+a[i]。然后如果改变摸个位置的幅度,只需维护这个位置所在的块即可(可以节省时间);

AC代码为:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>

using namespace std;  
typedef long long ll;  
const int N=200005;  
int belong[N],block,num,l[N],r[N],x[N],y[N];  

int a[N],n,m;  
  
void build()  
{  
    block=sqrt(n);     
    num=n/block;if(n%block) num++;  
    for(int i=1;i<=num;i++)  
        l[i]=(i-1)*block+1,r[i]=i*block;  
    r[num]=n;  
    for(int i=1;i<=n;i++)  
        belong[i]=(i-1)/block+1;  
    for(int i=n;i>=1;i--)   
    {  
        if(i+a[i]>r[belong[i]])  
        {  
            x[i]=1;  
            y[i]=i+a[i];  
        }  
        else  
        {  
            x[i]=x[i+a[i]]+1;  
            y[i]=y[i+a[i]];  
        }  
    }  
}  
void update(int s,int k)  
{  
    a[s]=k;  
    for(int i=s;i>=r[belong[s]-1];i--)  
    {  
        if(i+a[i]>r[belong[i]])  
        {  
            x[i]=1;  
            y[i]=i+a[i];  
        }  
        else  
        {  
            x[i]=x[i+a[i]]+1;  
            y[i]=y[i+a[i]];  
        }  
    }  
}  
int query(int s)  
{  
    int res=0;  
    while(s<=n)  
    {  
        res+=x[s];  
        s=y[s];  
    }  
    return res;  
}  
int main()  
{  
    while(scanf("%d",&n)!=EOF)  
    {  
        for(int i=1;i<=n;i++)  
            scanf("%d",&a[i]);  
        build();  
        scanf("%d",&m);  
        int s,p,q;  
        for(int i=1;i<=m;i++)  
        {  
            scanf("%d",&s);  
            if(s==1)  
            {  
                scanf("%d",&p);  
                printf("%d\n",query(p+1));   
            }  
            if(s==2)  
            {  
                scanf("%d%d",&p,&q);  
                update(p+1,q);  
            }  
        }  
    }  
}

HYSBZ-2002弹飞绵羊的更多相关文章

  1. BZOJ 2002 弹飞绵羊(分块)

    题目:弹飞绵羊 这道题,据说是lct裸题,但是lct那么高级的数据结构,我并不会,所以采取了学长讲过的分块做法,我们对序列分块,可以定义两个数组,其中一个表示从当前位置跳出当前块需要多少步,另一个数组 ...

  2. [bzoj] 2002 弹飞绵羊 || LCT

    原题 简单的LCT练习题. 我们发现对于一个位置x,他只能跳到位置x+k,也就是唯一的父亲去.加入我们将弹飞的绵羊定义为跳到了n+1,那么这就形成了一棵树.而因为要修改k,所以这颗树是动态连边的,那么 ...

  3. bzoj 2002: 弹飞绵羊 Link-Cut-Tree

    题目: Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置, ...

  4. bzoj 2002 弹飞绵羊 分块

    正解lct,然而本蒟蒻并不会.... 分块思路很清晰,处理出每个点弹出所在块所需要的步数及出去后的第一个位置 #include<cstdio> #include<cstring> ...

  5. BZOJ 2002 弹飞绵羊

    LCT 刚学LCT,对LCT的性质不太熟练,还需要多多练习.. 对每一个点,将其与它能够到达的点连一条虚边.弹出去的话就用n+1这个节点表示. 第一种操作我们需要从LCT的性质入手,问的问题其实就是x ...

  6. bzoj 2002 弹飞绵羊 lct裸题

    上一次用分块过了, 今天换了一种lct(link-cut tree)的写法. 学lct之前要先学过splay. lct 简单的来说就是 一颗树, 然后每次起作用的都是其中的某一条链. 所以每次如果需要 ...

  7. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 9071  Solved: 4652[Submi ...

  8. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 分块

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...

  9. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...

  10. bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 動態樹

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 4055  Solved: 2172[Submi ...

随机推荐

  1. awk 实用案例介绍

    awk 简介 • awk是 3 个姓氏的首字母,代表该语言的 3 个作者 • awk的版本有很多,包括: 旧版 awk,新版 awk(nawk), GNUawk(gawk)等 • awk程序有 awk ...

  2. [Bootstrap] Bootstrap学习笔记

    1.因为bootstrap用到了html5的特性,为了正常使用,需要在最开头加上<!DOCTYPE html> 2.Bootstrap需要JQuery才能正常工作,所以需要导入jquery ...

  3. 微擎修改 icon.jpg 后项目主页未变

    微擎修改 icon.jpg 后项目主页Logo未变 产生原因: 设置了自定义图标,但系统未找到该图标,就选择使用默认的起始图标 解决办法: 在项目根目录位置上传一个图标名为 icon-custom.j ...

  4. pat 1116 Come on! Let's C(20 分)

    1116 Come on! Let's C(20 分) "Let's C" is a popular and fun programming contest hosted by t ...

  5. 深入ObjC GCD中的dispatch group工作原理。

    本文是基于GCD的支持库libdispatch的源代码分析的结果或是用于作为源代码阅读的参考,尽量不帖代码,力求用UML图来说明工作流. 本文参考的源代码版本为v501.20.1,如有兴趣请自行到苹果 ...

  6. Docker从入门到掉坑(三):容器太多,操作好麻烦

    前边的两篇文章里面,我们讲解了基于docker来部署基础的SpringBoot容器,如果阅读本文之前没有相关基础的话,可以回看之前的教程. Docker 从入门到掉坑 Docker从入门到掉坑(二): ...

  7. 前端页面传来数组,后台用对象集合list接收数据的写法

    //保存页面显示应用$("#save").click(function(){ var data = [{"applicationtypeid":"65 ...

  8. JavaWeb04-JSP及会话跟踪技术

    JSP入门 1 JSP概述 1.1 什么是JSP JSP(Java Server Pages)是JavaWeb服务器端的动态资源.它与html页面的作用是相同的,显示数据和获取数据. 1.2 JSP的 ...

  9. pdf 在线预览之 vue-pdf插件

    vue-pdf   支持到ie11npm安装:npm install --save vue-pdf 组件template: <div class="show-pdf"> ...

  10. Java数组使用以及foreach循环

    Java数组使用以及foreach循环 二话不说,先甩一个简单的程序: final int NUM= 10; int[] arrays = new int[NUM]; System.out.print ...