【BZOJ2002】[HNOI2010] 弹飞绵羊(大力分块)
大致题意: 有\(n\)个弹力装置,当到达第\(i\)个装置时,会被弹到第\(i+k_i\)个装置,若不存在第\(i+k_i\)个装置,就会被弹飞。有两种操作,一种操作是将\(k_x\)改为\(y\),另一种操作是询问从\(x\)出发被弹几次后会被弹飞。
考虑分块
这题可以用分块来做。
我们可以将弹力装置进行分块,对于每一块的弹力装置,可以先预处理出每个弹力元素弹出这个块之后到达的位置\(nxt_x\)以及需要的步骤\(val_x\)。
对于询问操作,从询问的\(x\)出发,每一次将\(ans\)加上\(val_x\),然后将\(x\)更新为\(nxt_x\),直至\(x\)大于\(n\),由于每个块最多被经过一次,因此时间复杂度是\(O(\sqrt n)\)的。
而对于修改操作,只要修改一个块内的\(nxt\)和\(val\)即可,不难发现修改也是\(O(\sqrt n)\)的。
因此总复杂度\(O(m\sqrt n)\),对于\(n≤200000,m≤100000\)的数据跑起来毫无压力。
代码
#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define LL long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define tc() (A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++)
#define pc(ch) (pp_<100000?pp[pp_++]=(ch):(fwrite(pp,1,100000,stdout),pp[(pp_=0)++]=(ch)))
#define N 200000
#define SIZE 450
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
int pp_=0;char ff[100000],*A=ff,*B=ff,pp[100000];
using namespace std;
int n,Q,blo,a[N+5],pos[N+5],nxt[N+5],val[N+5];
inline void read(int &x)
{
x=0;static char ch;
while(!isdigit(ch=tc()));
while(x=(x<<3)+(x<<1)+ch-48,isdigit(ch=tc()));
}
inline void write(int x)
{
if(x>9) write(x/10);
pc(x%10+'0');
}
int main()
{
register int i,op,x,y,limit,ans;
for(read(n),blo=sqrt(n),i=1;i<=n;++i) read(a[i]),pos[i]=(i-1)/blo+1;
for(i=n;i;--i)//先预处理出nxt[]和val[]数组
{
if(pos[i]^pos[nxt[i]=i+a[i]]) val[i]=1;//如果直接弹出这个块,那么所需步骤为1
else val[i]=val[nxt[i]]+1,nxt[i]=nxt[nxt[i]];//否则,步骤数就是它所到达的下一个节点弹出这个块的步骤,且它弹出这个块后到达的元素就是它所到达的下一个节点弹出这个块后到达的元素
}
for(read(Q);Q;--Q)
{
read(op),read(x),++x;//因为数据是0~n-1编号的,而我习惯于从1~n编号,因此将读入的编号x加1
if(op^2)//对于询问操作
{
for(ans=0;x<=n;x=nxt[x]) ans+=val[x];//将ans加上x弹出当前块所需的步骤,并将x更新为它弹出当前块后到达的节点
write(ans),pc('\n');//输出ans
}
else
{
for(read(y),a[x]=y,limit=(pos[x]-1)*blo+1,i=pos[x]*blo;i>=limit;--i)//更新这个块中的信息
{
if(pos[i]^pos[nxt[i]=i+a[i]]) val[i]=1;//和初始化的代码差不多
else val[i]=val[nxt[i]]+1,nxt[i]=nxt[nxt[i]];
}
}
}
return fwrite(pp,1,pp_,stdout),0;
}
【BZOJ2002】[HNOI2010] 弹飞绵羊(大力分块)的更多相关文章
- BZOJ2002[Hnoi2010]弹飞绵羊——LCT
题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系 ...
- Bzoj2002/洛谷P3203 [HNOI2010]弹飞绵羊(分块)
题面 Bzoj 洛谷 题解 大力分块,分块大小\(\sqrt n\),对于每一个元素记一下跳多少次能跳到下一个块,以及跳到下一个块的哪个位置,修改的时候时候只需要更新元素所在的那一块即可,然后询问也是 ...
- 【bzoj2002】弹飞绵羊(分块)
题目分析 题意:每个点都有一个值$v_i$,从一个点出发,每走到一个点,会跳到i+vi的位置,问需要跳多少次能跳出n?带修改. 此题可以用lct做,此处使用了分块:将序列分块后,每个点记录从此点最少跳 ...
- BZOJ2002 [HNOI2010] 弹飞绵羊
LCT access完了一定splay再用!!! 悲伤= = LCT裸题 把调出去设虚点n+1即可 //Love and Freedom. #include<cstdio> #includ ...
- [HNOI2010] 弹飞绵羊 (分块)
[HNOI2010] 弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上 ...
- 「洛谷P3202」[HNOI2010]弹飞绵羊 解题报告
P3203 [HNOI2010]弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一 ...
- 【BZOJ2002】弹飞绵羊(Link-Cut Tree)
[BZOJ2002]弹飞绵羊(Link-Cut Tree) 题面 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lost ...
- P3203 [HNOI2010]弹飞绵羊(LCT)
P3203 [HNOI2010]弹飞绵羊 LCT板子 用一个$p[i]$数组维护每个点指向的下个点. 每次修改时cut*1+link*1就解决了 被弹出界时新设一个点,权为0,作为终点表示出界点.其他 ...
- 洛谷 P3203 [HNOI2010]弹飞绵羊 解题报告
P3203 [HNOI2010]弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一 ...
- [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)
[BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree) 题面 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一 ...
随机推荐
- [Xcode 实际操作]四、常用控件-(14)使用UIWebView控件加载本地HTML
目录:[Swift]Xcode实际操作 本文将演示使用网页视图,加载并渲染网页代码. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit im ...
- click点击事件先后顺序的问题
//页面加载时,每秒钟调用一次var times = setInterval("loadFlws()","1000"); function loadFlws() ...
- 从技术 Leader 的招聘需求看,如何转岗为当前紧缺的大数据相关人才?
前段时间,跟候选人聊天的时候,一个有多年工作经验的资深 iOS 工程师告诉我,他最近正在学习 Machine Learning 相关的知识.他觉得,对于程序员来说,技术进步大大超过世人的想象,如果你不 ...
- POJ3696 The Luckiest Number 欧拉定理
昨天终于把欧拉定理的证明看明白了...于是兴冲冲地写了2道题,发现自己啥都不会qwq 题意:给定一个正整数L<=2E+9,求至少多少个8连在一起组成正整数是L的倍数. 这很有意思么... 首先, ...
- Django - 权限(3)- 动态显示二级菜单
一.动态显示二级菜单 上篇随笔中,我们实现了动态显示一级菜单,现在考虑这样一种情况,用户的菜单权限比较多,这个时候全部并列展现在左侧菜单就不合适了,所以,现在有这样一个需求,即把用户的菜单权限分类,划 ...
- JQuery的extend扩展方法
jQuery.extend 函数使用详解 JQuery的extend扩展方法: Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去 ...
- java——变量、jvm内存划分
基本数据变量类型:byte.short.int.long.float.double.boolean.char eg : int i = 1; 引用数据变量类型:数组.类.接口.枚举.注解 eg : S ...
- (转)不看绝对后悔的Linux三剑客之sed实战精讲
不看绝对后悔的Linux三剑客之sed实战精讲 原文:http://blog.51cto.com/hujiangtao/1923718 二.Linux三剑客之sed命令精讲 1,前言 我们都知道,在L ...
- JAVA多线程面试题目
1,java中有几种方法可以实现一个线程? 答:在Java中实现一个线程有两种方法,第一是实现Runnable接口实现它的run()方法,第二种是继承Thread类,覆盖它的run()方法.这两种方法 ...
- VirtualBox 在Centos 7 中安装增强功能 (共享文件夹)
1.分配光驱 2.安装相关依赖包 yum install -y bzip2 gcc gcc-devel gcc-c++ gcc-c++-devel make kernel-d 3.创建临时文件夹 mk ...