——BZOJ2002

Description

某天,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 \le 10000\),对于\(100\%\)的数据\(n \le 200000\),\(m \le 100000\)

Output

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

Sample Input

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

Sample Output

2
3

Analysis

这道题的正解是LCT?

不过这是省选题,一定有其他的解法,这里就有一个分块做法。

O(n)维护两个数组to和outto,to代表每个位置跳到块内最后一个位置的最少步数,outto表示这个位置跳到第二个块的新位置。这两个数组倒着维护。

然后就能做了。

询问和修改的时间复杂度都是\(O(\sqrt n)\),因为一共\(\sqrt n\)个块,每个块内\(\sqrt n\)个元素。

code

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int read()
{
int ans = 0,op = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-') op = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
ans *= 10;
ans += ch - '0';
ch = getchar();
}
return ans * op;
}
const int maxn = 2e5 + 5;
int seq[maxn];
int blo[10005];
int to[maxn];
int outto[maxn];
int m,n;
int cnt,num,cntt=1;
int qpos(int x)
{
return x % cnt == 0 ? x / cnt : x / cnt + 1;
}
int qlast(int x)
{
if(qpos(x) == num)
return n;
return cnt * qpos(x);
}
int qfirst(int x)
{
return cnt * (qpos(x) - 1) + 1;
}
int main()
{
n = read();
cnt = sqrt(n);
num = qpos(n);
for(int i=1;i<=n;i++)
seq[i] = read();
for(int i=n;i>=1;i--)
{
if(i + seq[i] > qlast(i))
{
to[i] = i + seq[i];
outto[i] = 1;
}
else
{
to[i] = to[i+seq[i]];
outto[i] = outto[i+seq[i]] + 1;
}
}
// printf("\n***\n");
// for(int i=1;i<=n;i++)
// printf("%d ",to[i]);
// printf("\n");
// for(int i=1;i<=n;i++)
// printf("%d ",outto[i]);
// printf("\n***\n");
m = read();
for(int ct=1;ct<=m;ct++)
{
int ju;
ju = read();
if(ju == 1)
{
int x,ans;
x = read();
x+=1;
ans = outto[x];
x = to[x];
while(x <= n)
{
ans += outto[x];
x = to[x];
}
printf("%d\n",ans);
}
else
{
int x,k;
x = read();
k = read();
x+=1;
seq[x] = k;
for(int i=x;i>=qfirst(x);i--)
{
if(i + seq[i] > qlast(i))
{
to[i] = i + seq[i];
outto[i] = 1;
}
else
{
to[i] = to[i+seq[i]];
outto[i] = outto[i+seq[i]] + 1;
}
}
}
}
return 0;
}

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

  1. 【codevs2333】&【BZOJ2002】弹飞绵羊[HNOI2010](分块)

    我其实是在codevs上看到它的题号后才去做这道题的...2333... 题目传送门:codevs:http://codevs.cn/problem/2333/ bzoj:http://www.lyd ...

  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. P3203 [HNOI2010]弹飞绵羊(LCT)

    P3203 [HNOI2010]弹飞绵羊 LCT板子 用一个$p[i]$数组维护每个点指向的下个点. 每次修改时cut*1+link*1就解决了 被弹出界时新设一个点,权为0,作为终点表示出界点.其他 ...

随机推荐

  1. 29.python环境搭建

    新的笔记本上搭建的python运行环境:1.首先现在下载python版本,我这里拿的是之前用的3.5老版本 2.双击安装(勾选 add Python3.5 to path) 3.检测是否安装成功 4. ...

  2. Echarts属性大全(及时更新最新信息)

    echarts属性的设置(完整大全)   // 全图默认背景  // backgroundColor: ‘rgba(0,0,0,0)’, // 默认色板 color: ['#ff7f50','#87c ...

  3. JetBrains 产品线破解方法

    参考: 1.https://www.jianshu.com/p/f404994e2843 2.https://xclient.info/s/intellij-idea.html#versions 3. ...

  4. 深入理解Java虚拟机之JVM垃圾回收随笔

    1.对象已经死亡? 1.1引用计数法:给对象中添加一个引用计数器,每当有一个地方引用他时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器都为0的对象就是不可能再被使用 的.但是它很难解决 ...

  5. c# System.Console

    System.Console类公开了和操作控制台相关的有用的静态字段和静态方法.下面是System.Console中一些较为重要的方法. public static void Beep()该方法播放蜂 ...

  6. php 自制简单路由类 望大神指点

    class route{ /** @var null 模块 */ private static $module = null; /** @var null 控制器 */ private static ...

  7. vo与po

    场景: 控制层使用vo对象,数据层使用po对象,业务层负责将po对象转换成vo对象传递给控制层 vo和po对象之间转换可以用BeanUtils.copyProperties(vo, po);方法 如果 ...

  8. Spring Boot与Docker部署

    开启Docker远程访问 首先需要开启docker远程访问功能,以便可以进行远程操作. CentOS 6 修改/etc/default/docker文件,重启后生效(service docker re ...

  9. 大数据架构工具hadoop

    Hadoop是一个开源框架,它允许在整个集群使用简单编程模型计算机的分布式环境存储并处理大数据.它的目的是从单一的服务器到上千台机器的扩展,每一个台机都可以提供本地计算和存储. “90%的世界数据在过 ...

  10. form表单中$_FILES数组的使用

    <form enctype="multipart/form-data" action="upload.php" method="post&quo ...