弹飞绵羊[HNOI2010]
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]的更多相关文章
- 【codevs2333】&【BZOJ2002】弹飞绵羊[HNOI2010](分块)
我其实是在codevs上看到它的题号后才去做这道题的...2333... 题目传送门:codevs:http://codevs.cn/problem/2333/ bzoj:http://www.lyd ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 9071 Solved: 4652[Submi ...
- 【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]]即为答 ...
- 【bzoj2002】[Hnoi2010]Bounce 弹飞绵羊 分块
[bzoj2002][Hnoi2010]Bounce 弹飞绵羊 2014年7月30日8101 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 分块
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...
- bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 動態樹
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 4055 Solved: 2172[Submi ...
- bzoj 2002 : [Hnoi2010]Bounce 弹飞绵羊 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 题面: 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: ...
- P3203 [HNOI2010]弹飞绵羊(LCT)
P3203 [HNOI2010]弹飞绵羊 LCT板子 用一个$p[i]$数组维护每个点指向的下个点. 每次修改时cut*1+link*1就解决了 被弹出界时新设一个点,权为0,作为终点表示出界点.其他 ...
随机推荐
- 获取物理内存total值和used值
1.使用 free -m 查看 2.物理内存total值 # free -m | grep Mem | awk '{print $2}' 3.物理内存used值 # free -m | grep Me ...
- V先生:信息流广告标题党必备的500个热词
稍微没有全都偏,简直仅仅只永远, 已经曾经就竟然,将要立刻刚偶然, 渐渐终于决忽然,难道连续又再三, 也许必须很非常,最太十分更马上, 越极总挺常常再,屡次一定也不还. 你一定不知道.如何.最.咋.是 ...
- py库:threading
https://www.youtube.com/watch?v=DnTn3Yx-Nvg join功能: import threading import time def thread_job2(): ...
- ORM版学员管理系统
ORM版学员管理系统 班级表 表结构 class Class(models.Model): id = models.AutoField(primary_key=True) # 主键 cname = m ...
- Fiddler手机抓包设置
前提条件:1).电脑需要安装Fiddler2).测试手机需要支持Wifi3).测试手机与电脑需要同一网络4).所测APP需支持代理 三.设置Fiddler 1.(1)电脑端打开安装好的的fiddler ...
- 代码详解:TensorFlow Core带你探索深度神经网络“黑匣子”
来源商业新知网,原标题:代码详解:TensorFlow Core带你探索深度神经网络“黑匣子” 想学TensorFlow?先从低阶API开始吧~某种程度而言,它能够帮助我们更好地理解Tensorflo ...
- 宝塔面板安装在根目录www下
不能重装,重装防火墙要重新关闭. 安装时要主要更改文件权限.
- windows上不能启动Apache,遇到错误的方法之一
最近在2008服务器上安装apache,出现了No installed ConfigArgs for the service "Apache2.4"这个错误. 启动不了,重装了一样 ...
- oracle中 特殊字符 转义 (&)
在dml中,若操作的字符中有 & 特殊字符,则会被oracle视作是输入变量的标志,此时需要用转义字符来进行转义. 1.”&“ 转义 这个是Oracle里面用来识别自定义变量的设置,现 ...
- Apache Flink 数据流编程模型
抽象等级(Levels of Abstraction) Flink提供不同级别的抽象来开发流/批处理应用程序. Statefule Stream Processing: 是最低级别(底层)的抽象,只提 ...