P3203 [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。对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000

输出格式:

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

输入输出样例

输入样例#1:

4
1 2 1 1
3
1 1
2 1 1
1 1
输出样例#1:

2
3

思路:

  分块什么的

坑点:

  1.注意是从0号元素开始!!!

  2.在luogu上最好不要用next数组...

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std; const int M = ;
const int N = ;
int n,m;
int k[M],steps[M],nxt[M];
///step数组存的是需要多少步跳出当前块
///next数组存的是跳到(下一块)的下一个点
int len,ks,kuai[M],l[N],r[N];///分块 void Builds()
{
///块的长度
len=sqrt(n);
///块的个数
ks=len;
if(n%ks) ks++;
///分块
for(int i=;i<n;i++)
kuai[i]=(i-)/len;
/*
因为块数是从0号开始计数的,
当i==(√n)时如果不进行-1,
会被分到第一块,
但事实上它是第0块的,
所以进行-1
*/
for(int i=;i<=ks;i++)
{
l[i]=(i-)*len;
///r[i]=i*len-1中-1的原因是:
///因为数组是从0号开始储存的
r[i]=i*len-;
}
///将最后一块的右端手动设置为n的长度
r[ks]=n;
for(int i=n-;i>=;i--)
{
int now=i+k[i];
///如果下一步跳到的地方已经跳出最远的距离n的话
if(now>=n)
///更新步数:跳一步就跳出去
steps[i]=,
///这里重要!需要手动将next数组设置一个不可能出现的数值
nxt[i]=-;
else
///假如在同一块中
if(kuai[i]==kuai[now])
///更新步数,i的步数由now的步数多跳一步来到当前(点)位置
steps[i]=steps[now]+,
///更新接下来跳到的点是...
nxt[i]=nxt[now];
else
///不在一块中
steps[i]=,
///跳到now这个点
nxt[i]=now;
}
} int ask(int pre)
{
int ans=;
while(pre!=-)
{
ans+=steps[pre];
pre=nxt[pre];
}
return ans;
} int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
scanf("%d",&k[i]);
///开始分块
Builds();
scanf("%d",&m);
for(int i=,c;i<m;i++)
{
scanf("%d",&c);
if(c==)
{
int pre;
scanf("%d",&pre);
printf("%d\n",ask(pre));
}
else
{
int pre,ki;
scanf("%d%d",&pre,&ki);
///更新k值
k[pre]=ki;
///因为更改k之后只会影响到当前块,并且只会影响他前面的
for(int j=pre;j>=l[kuai[pre]];j--)
{
int now=j+k[j];
if(now>=n)
steps[j]=,
nxt[j]=-;
else
if(kuai[j]==kuai[now])
steps[j]=steps[now]+,
nxt[j]=nxt[now];
else
steps[j]=,
nxt[j]=now;
}
}
}
return ;
}

luoguP3203 [HNOI2010]BOUNCE 弹飞绵羊的更多相关文章

  1. [luoguP3203][HNOI2010]BOUNCE 弹飞绵羊(LCT)

    传送门 每个点都会跳到另一个点,连边就是一棵树. 更改弹力就是换边. 求一个点跳多少次跳到终点就是求这个点的深度,那么只需要维护 size 域,access(n + 1) 然后 splay(x),求 ...

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

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

  3. 【bzoj2002】[Hnoi2010]Bounce 弹飞绵羊 link-cut-tree

    2016-05-30 11:51:59 用一个next数组,记录点x的下一个点是哪个 查询时,moveroot(n+1),access(x),splay(x) ,输出size[ch[x][0]]即为答 ...

  4. 【bzoj2002】[Hnoi2010]Bounce 弹飞绵羊 分块

    [bzoj2002][Hnoi2010]Bounce 弹飞绵羊 2014年7月30日8101 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀 ...

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

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

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

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

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

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

  8. bzoj 2002 : [Hnoi2010]Bounce 弹飞绵羊 (LCT)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 题面: 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: ...

  9. 【BZOJ2002】 [Hnoi2010]Bounce 弹飞绵羊

    BZOJ2002 [Hnoi2010]Bounce 弹飞绵羊 Solution 很早以前写的一道分块题,最近在搞LCT,又做了一遍. 1.LCT做法 看到这种动态修改,想下LCT怎么维护. 修改操作就 ...

随机推荐

  1. SpreadJS 纯前端表格控件 V12.2 发布更新

    用不到100行代码,在前端实现Excel的全部功能 千万前端开发者翘首企盼,SpreadJS V12.2 终发布更新:六大功能特性,带来更多便利,用不到100行代码,在前端实现Excel的全部功能! ...

  2. 使用javascript完成一个简单工厂设计模式。

    在JS中创建对象会习惯的使用new关键字和类构造函数(也是可以用对象字面量). 工厂模式就是一种有助于消除两个类依赖性的模式. 工厂模式分为简单工厂模式和复杂工厂模式,这篇主要讲简单工厂模式. 简单工 ...

  3. java导入导出Excel文件

    package poi.excel; import java.io.IOException; import java.io.InputStream; import java.io.OutputStre ...

  4. C++学习 之 变量和常量的使用(笔记)

    一.变量 1.对变量含义的理解: 变量就像是经过工厂加工后有一定容量的容器.在变量定义时,系统充当了工厂的角色,按照类型为变量分配相应的空间.定义完成的变量可以存放相应类型的值,存放的值大于变量所能接 ...

  5. 树上选两点(使最短)树的直径+bfs

    题意: 给你一颗树,让你放两个点,放在哪里的时候任意点到某个最近的消防站最远值最小. 思路: 树的直径类题目. 首先我们想两个点会把整棵树分成两个团,所以肯定会在树的某个链上切开. 而且要切一定切在树 ...

  6. PHP 补零操作

    str_pad(string,length,pad_string,pad_type)//参数 描述string //必需.规定要填充的字符串.length //必需.规定新的字符串长度.如果该值小于字 ...

  7. layui2.5 修改layuicms

    雷哥layui2.5版本学习 学习地址: https://www.bilibili.com/video/av59813890/?p=30 注意: 修改layuicms时注意下面是缓存的js, < ...

  8. USB键盘驱动分析

    简介 本文介绍USB驱动程序编写的流程,分析一个键盘的USB程序,基于linux-2.6.39 USB驱动概要 分层 主机层面的USB驱动的整体架构可以分成4层,自顶到下依次是 1.USB设备驱动:本 ...

  9. EBS自动行号,行金额自动汇总到头,金额根据币种编号总结

    一.自动行号实现 1.方法一: 只需要将“序号”定义成公式,并将公式设置为:get_block_property('block_name',current_record)就可以实现了,或者把这行语句放 ...

  10. AngularJS 在实际应用中优缺点

    AngularJS 在实际应用中优点:模板功能强大丰富,并且是声明式的,自带了丰富的Angular指令:是一个比较完善的前端MV*框架,包含模板,数据双向绑定,路由,模块化,服务,过滤器,依赖注入等所 ...