分块 (貌似能用LCT做,反正我现在还不会) BZOJ 2002
2002: [Hnoi2010]Bounce 弹飞绵羊
Time Limit: 10 Sec Memory Limit: 259 MB
Submit: 9844 Solved: 5070
[Submit][Status][Discuss]
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<=10000,对于100%的数据n<=200000,m<=100000
Output
对于每个i=1的情况,你都要输出一个需要的步数,占一行。
Sample Input
1 2 1 1
3
1 1
2 1 1
1 1
Sample Output
3
HINT
Source
思路:感觉这个如果说用分块的话感觉是基础题?
总体思路就是分成sqrt(n)块,然后每次都对这个块内进行更新, need表示每次走的步数,我们就只要for(j = r[i]; j >= l[i]; j--) 来逆序迭代更新就好了。
//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = * ;
int n, m;
int step[maxn];
int l[maxn], r[maxn], belong[maxn], block, num;
int to[maxn], need[maxn]; void build(){
block = sqrt(n); num = n / block;
if (n % block) num++;
for (int i = ; i <= num; i++){
l[i] = (i - ) * block + , r[i] = i * block;
}
for (int i = ; i <= n; i++)
belong[i] = (i - ) / block + ;
} void update(int be){
for (int i = l[be]; i <= r[be]; i++)
to[i] = -, need[i] = ;
for (int i = r[be]; i >= l[be]; i--){
int nxtpos = i + step[i];
if (nxtpos > n) nxtpos = n + ;
if (belong[nxtpos] != be){//如果只走一步,且两个不是同一个块
to[i] = nxtpos; need[i] = ;
}
else {//同一个块
need[i] = ;
need[i] += need[nxtpos];
to[i] = to[nxtpos];
}
}
} void query(int pos){
int cnt = ;
while (pos <= n){
cnt += need[pos];
pos = to[pos];
}
printf("%d\n", cnt);
} int main(){
cin >> n;
for (int i = ; i <= n; i++){
scanf("%d", step + i);
}
build();
memset(to, -, sizeof(to));
for (int i = ; i <= num; i++){
update(i);
}
/*
for (int i = 1; i <= n; i++){
printf("to[%d] = %d need[%d] = %d\n", i, to[i], i, need[i]);
}
*/
cin >> m;
for (int i = ; i <= m; i++){
int a, b, c;
scanf("%d%d", &a, &b); b++;
if (a == ){
scanf("%d", &c);
step[b] = c;
update(belong[b]);
}
else {
query(b);
}
}
return ;
}
关键:分块的魅力在于每次不需要将序列全部更新,而是只需要更新其中的片段
分块 (貌似能用LCT做,反正我现在还不会) BZOJ 2002的更多相关文章
- BZOJ 2002 && BZOJ 2409 LCT && BZOJ 3282 初步练习
#include <cstdio> ; inline void Get_Int(int & x) { ; ') ch=getchar(); +ch-'; ch=getchar(); ...
- 以 BZOJ 2002 为例学习有根树LCT(Link-Cut Tree)
以BZOJ 2002 弹飞绵羊为例学习有根树LCT(Link-Cut Tree) 注:本文非常简单,只涉及有根树LCT,对于无根树,LCT还有几个本文没有提到的操作,以后慢慢更新 =v= 知识储备 [ ...
- LCT做题笔记
最近几天打算认真复习LCT,毕竟以前只会板子.正好也可以学点新的用法,这里就用来写做题笔记吧.这个分类比较混乱,主要看感觉,不一定对: 维护森林的LCT 就是最普通,最一般那种的LCT啦.这类题目往往 ...
- Bootstrap 貌似不错,先做一下记录
Bootstrap 简洁.直观.强悍的前端开发框架,让web开发更迅速.简单. http://www.bootcss.com/
- 【BZOJ 2002】【Hnoi 2010】弹飞绵羊 分块||Link Cut Tree 两种方法
ShallWe,Yveh,hmy,DaD3zZ,四人吃冰糕从SLYZ超市出来后在马路上一字排开,,,吃完后发现冰糕棍上写着:“向狮子座表白:愿做你的小绵羊”,,, 好吧在这道题里我们要弹飞绵羊,有分块 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 分块
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...
- bzoj 2002 弹飞绵羊 分块
正解lct,然而本蒟蒻并不会.... 分块思路很清晰,处理出每个点弹出所在块所需要的步数及出去后的第一个位置 #include<cstdio> #include<cstring> ...
- bzoj 2002 : [Hnoi2010]Bounce 弹飞绵羊 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 题面: 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: ...
- bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊(分块算法)
传送门 题意: 中文题意,不再赘述. 题解: 下午在补分块算法的相关知识,看到某大神博客推荐的这道题目,就试着做了做: TLE了一下午可还行: 我的思路: 将这 n 个点分成 sqrt(n) 块: i ...
随机推荐
- mysql 多查询临时表的运用
SELECT * from (select count(*) imgCount1 from imagetable where SeriesID = '1201061992020630292018092 ...
- UVA 10328 - Coin Toss dp+大数
题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...
- 周总结<6>
周次 学习时间 新编写代码行数 博客量(篇) 学到知识点 13 10 100 2 网页设计:邻接矩阵深度以及广度遍历
- 第八章 Mysql运算符
算术运算符 符号 表达式形式 作用 + x1+x2 加法 - x1-x2 减法 * x1*x2 乘法 / x1/x2 除法 div x1 div x2 同上 % x1%x2 取余 mod mod(x1 ...
- inotify 工具 是一种强大的、细粒度的、异步文件系统监控机制
前言:Inotify是一种强大的.细粒度的.异步文件系统监控机制,它满足各种各样的文件监控需要,可以监控文件系统的访问属性.读写属性.权限属性.删除创建.移动等操作,也就是可以监控文件发生的一切变化. ...
- div跟随鼠标移动
1.目标是实现div跟随鼠标而移动,分三种情况进行实现 a)首先获取div,进行绑定鼠标移动事件,给div开启定位功能 第一种实现方式,假如body的大小跟页面大小一样,则可以用这个方法. 1)获取鼠 ...
- PAT 甲级 1077 Kuchiguse
https://pintia.cn/problem-sets/994805342720868352/problems/994805390896644096 The Japanese language ...
- javascript之彻底理解this
彻底理解this,需要彻底理解函数 函数是复杂类型,存储在堆中. 函数是独立的, 对象中的方法只是对象中有个函数的引用 函数被调用时,调用者会像被调用者提供个上下文环境, 这个环境就是this 构造 ...
- Java多线程编程(学习笔记)
一.说明 周末抽空重新学习了下多线程,为了方便以后查阅,写下学习笔记. 有效利用多线程的关键是理解程序是并发执行而不是串行执行的.例如:程序中有两个子系统需要并发执行,这时候需要利用多线程编程. 通过 ...
- PC和FPGA间的串口通信实现
应用笔记 V1.0 2015/03/26 PC和FPGA间的串口通信实现 概述 本文将介绍PC和FPGA间的串口通信实现的基本思路和Verilog代码,对于通信而言,收发双方都要有相应的控制. ...