分块(似乎还有一种动态树(LCT)做法)

第一次学习分块,似乎有点小激动

这是黄学长的分块入门博客「分块」数列分块入门1 – 9 by hzwer


题目描述

某天,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。

输出格式:

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

说明

对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000


不看数据范围的话,题目还是挺友好的对不对...用f[i]表示在第i个装置上出发几次后被弹飞,毕竟对于任意i的f[i]是唯一的。

然而,然而题目要求在线更新并询问……

那第一感觉就是路径压缩,每一次更改ki之后向后修改f[i]并修改f[i + k[i]]。但实际上这样会有大量的冗余操作,有可能它之后跳的位置都没有被修改过。

那么在f[i]上挂链记录跳到i的位置吗?每次修改ki向前更新?

然而这样又是O(n)的更新复杂度……要是遇上1 1 1 1 1...的无良数据呢……

所以就有了“分块”这种奇妙的操作……呃其实我觉得分块就是一种有效优化的暴力嘛(但是似乎这样看来有些其他算法也是暴力嘛(是亦彼也,彼亦是也))

我们把n分成m块,一般情况下m=sqrt(n)(不过具体题目具体分析,通常m的大小有三种方式确定:1.m=sqrt(n)  2.用大数据观察,手调m  3.分析并使用均值不等式)

由于块大小是远远小于总数的,我们每一次更新只要在块内,时间复杂度就是足够的。至于后续的处理,分块也能够起到优化作用。例如本题,用nxt[i]记录i在跳出当前块后跳到的位置,w[i]记录i跳出当前块的步数,不仅在查询时可省去大量的块内跳跃的模拟,在更新时候逆序处理也就能够利用已处理的w[],nxt[],进一步奇妙优化。(是的没有错,我因为暴力更新块内元素,即便开O2并且把m=sqrt(n)*2/7了仍然最后一点TLE)

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std; int k[],w[],nxt[],m,n;
int bl[],blo; inline int dist(int x)
{
if (x >= n)return ;
return dist(nxt[x]) + w[x];
}
inline int away(int x)
{
int r,cnt = ,t = x;
if ((bl[x])*blo - > n-)r = n-;
else r = (bl[x])*blo - ;
cnt++;x+=k[x];
if (x <= r){
cnt += w[x];
x = nxt[x];
}
nxt[t] = x;
return cnt;
} int main()
{
scanf("%d",&n);
blo = sqrt(n);
if (blo > )blo = (blo*)/;
for (int i=; i<n; i++)
{
scanf("%d",&k[i]);
bl[i] = i/blo + ;
}
memset(w, , sizeof(w));
for (int i=n-; i>=; i--) w[i] = away(i);
scanf("%d",&m);
for (int i=; i<=m; i++)
{
int fl, x, y;
scanf("%d%d",&fl,&x);
if (!(fl-))printf("%d\n",dist(x));
else{
scanf("%d",&y);
k[x] = y;
for (int j=x; j>=(bl[x]-)*blo; j--)w[j] = away(j);
}
}
return ;
}

对了还有一个坑点,本题元素下标自0开始

【分块】[HNOI2010]弹飞绵羊&分块大法祭的更多相关文章

  1. [HNOI2010] 弹飞绵羊 (分块)

    [HNOI2010] 弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上 ...

  2. [luogu3203 HNOI2010] 弹飞绵羊 (分块)

    传送门 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置, ...

  3. 洛谷 P3203 [HNOI2010]弹飞绵羊 分块

    我们只需将序列分成 n\sqrt{n}n​ 块,对于每一个点维护一个 val[i]val[i]val[i],to[i]to[i]to[i],分别代表该点跳到下一个块所需要的代价以及会跳到的节点编号.在 ...

  4. P3203 弹飞绵羊-分块

    P3203 弹飞绵羊-分块 观察数据范围,发现可以分块.只需要处理每个点跳出所在块后的位置和次数即可.目的是为了加速查询并降低修改复杂度. 对于修改,重构整个块内信息即可. 时间复杂度正确的一批 具体 ...

  5. 「洛谷P3202」[HNOI2010]弹飞绵羊 解题报告

    P3203 [HNOI2010]弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一 ...

  6. P3203 [HNOI2010]弹飞绵羊(LCT)

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

  7. 洛谷 P3203 [HNOI2010]弹飞绵羊 解题报告

    P3203 [HNOI2010]弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一 ...

  8. [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)

    [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree) 题面 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一 ...

  9. [Luogu P3203] [HNOI2010]弹飞绵羊 (LCT维护链的长度)

    题面 传送门:洛谷 Solution 这题其实是有类似模型的. 我们先考虑不修改怎么写.考虑这样做:每个点向它跳到的点连一条边,最后肯定会连成一颗以n+1为根的树(我们拿n+1代表被弹出去了).题目所 ...

随机推荐

  1. php-fpm 高并发 参数调整

    工作中经常会遇到会给客户配置服务器,其中有的客户还会有并发量要求,其中也会必须要用负载均衡承载压力的.增加服务器数量肯定能有效的提升服务器承载能力,但只有根据目前已有配置设置好单台服务器才能更好的发挥 ...

  2. C#主从表查询

    软件的使用必然涉及到主表和子表的操作,我们先在SQLite中创建子表.比如 创建一学生信息表做主表,再创建一个学生成绩表做子表.然后我们在程序中成绩 方法来连接子表. 判断bindingsource中 ...

  3. java面试基础问题

    1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致. 2.Java有 ...

  4. PostgreSQL - 用psql 运行SQL文件

    对于预先写好的SQL文件,比如/home/user1/updateMyData.sql, 可以有两种方式来运行这个SQL文件. 方式一:连接db后执行SQL文件 首先通过psql连接到对应的db: p ...

  5. canvas常用画法整理

    代码Canvas.htm <!DOCTYPE html> <html lang="en"> <head> <title>canvas ...

  6. [题解]luogu_AT1224_JOIOJI

    https://www.cnblogs.com/fengzhiyuan/p/7588443.html 不会map,有点菜 1.要想知道三个字母出现次数相等, 为J [ i ]-J [ j ]== O[ ...

  7. HDU-1263(STL+排序)

    水果 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...

  8. mac Latex dvipdfm 缺少字体错误 Failed to read UCS2/UCS4 TrueType cmap

    dvipdfmx 命令产生 ** ERROR ** Failed to read UCS2/UCS4 TrueType cmap... 错误的原因是没有把 simsun.ttf simkai.ttf ...

  9. 重新安装Magento2 Module

    如何重新安装Magento2的Module? 分类 2 类: Module是通过 composer 安装的:在命令行输入:php bin/magento module:uninstall Module ...

  10. hihocoder1860 最大异或和

    思路: 把N个前缀异或和插入一棵trie树中,然后对每个前缀异或和x计算能使x ^ y最大的前缀异或和y.利用了异或运算的a ^ b ^ a = b的性质. 参考了https://cloud.tenc ...