弹飞绵羊[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,作为终点表示出界点.其他 ...
随机推荐
- Java架构师技能发展脑图
图中还有好多东西不会,先把图保存好,逐项击破
- py3,休息时间玩点小把戏
100以内奇数: ls = [x for x in range(100) if x % 2 == 1] 100以内偶数: ls = list(x for x in range(100) if x % ...
- pymysql -转自https://www.cnblogs.com/chenhaiming/p/9883349.html#undefined
PyMysql的几个重要方法 connect函数:连接数据库,根据连接的数据库类型不同,该函数的参数也不相同.connect函数返回Connection对象. cursor方法:获取操作数据库的Cur ...
- Delphi中Chrome Chromium、Cef3学习笔记(五)
原文 http://blog.csdn.net/xtfnpgy/article/details/48489489 一.模拟移动鼠标 // SetCursorPos(StrToInt(Edit ...
- 关于VMware虚拟机安装镜像时黑屏的解决办法
新下载的VMware14,设置了新的虚拟机,镜像放的是ubuntu系统,然后开机要安装系统的时候黑屏,并没有进入到安装系统的界面 解决办法:在管理员权限下打开cmd,然后运行netsh winsock ...
- 虚拟机安装及ubuntu-16.04.3-desktop-amd64.iso映像文件的安装
虚拟机安装及ubuntu-16.04.3-desktop-amd64.iso映像文件 搞了大半天才搞清楚装linux的前提是要先安装虚拟机的 先下载虚拟机,在然后创建虚拟机,在虚拟机里面再安装linu ...
- rem_750
/* fix the code flash the page */ var globalWidth = document.documentElement.clientWidth;//window.in ...
- document.compatMode 浏览器渲染模式判定利器
在加了DOCTYPE的页面document.compatMode输出CSS1Compat,不管加的是XHTML的还是HTML5的DOCTYPE.没有加的输出BackCompat. BackCompat ...
- 初识TCP协议
一.引言 发送一段TCP数据大致需要经过:用户封装 –> TCP封装 –> IP封装 –>帧封装 Note:用户封装没啥好说的,都是客户自己决定的,在一些简单的应用情况下,这个步骤可 ...
- CSS 图像高级 径向渐变
径向渐变 径向渐变使用 radial-gradient 函数语法. 这个语法和线性渐变很类似, 可以指定渐变结束时的形状 以及它的大小. 默认来说,结束形状是一个椭圆形并且和容器的大小比例保持一致. ...