BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 【LCT】【分块】
BZOJ2002 Hnoi2010 Bounce 弹飞绵羊
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
4
1 2 1 1
3
1 1
2 1 1
1 1
Sample Output
2
3
分块做法和LCT做法都有
先讲讲LCT,就是一个板子,把当前点和可以连到的点连边,然后修改弹力值就是把边断开然后重新连一条边,维护的答案是一条链的长度,在这里可以直接用LCT的性质直接维护siz
#include<bits/stdc++.h>
using namespace std;
#define N 200010
#define INF 1e9
inline int read(){
int res=0,w=1;char c=getchar();
while(!isdigit(c)&&c!='-')c=getchar();
if(c=='-')w=-1,c=getchar();
while(isdigit(c))res=(res<<1)+(res<<3)+c-'0',c=getchar();
return res;
}
struct Link_Cut_Tree{
int fa[N],son[N][2],siz[N];bool rev[N];
Link_Cut_Tree(){memset(rev,0,sizeof(rev));}
bool isroot(int t){return son[fa[t]][0]!=t&&son[fa[t]][1]!=t;}
bool Son(int t){return son[fa[t]][1]==t;}
void pushup(int t){siz[t]=siz[son[t][0]]+siz[son[t][1]]+1;}
void pushdown(int t){
if(!isroot(t))pushdown(fa[t]);
if(rev[t]){
rev[t]^=1;
rev[son[t][0]]^=1;
rev[son[t][1]]^=1;
swap(son[t][0],son[t][1]);
}
}
void rotate(int t){
int f=fa[t],g=fa[f];
bool a=Son(t),b=a^1;
if(!isroot(f))son[g][Son(f)]=t;fa[t]=g;
son[f][a]=son[t][b];fa[son[t][b]]=f;
son[t][b]=f;fa[f]=t;
pushup(f);pushup(t);
}
void splay(int t){
pushdown(t);
while(!isroot(t)){
int f=fa[t];
if(!isroot(f)){
if(Son(t)^Son(f))rotate(t);
else rotate(f);
}
rotate(t);
}
}
void access(int t){
int tmp=0;
while(t){
splay(t);
son[t][1]=tmp;
if(tmp)fa[tmp]=t;pushup(t);
tmp=t;t=fa[t];
}
}
void putroot(int t){
access(t);
splay(t);
rev[t]^=1;
}
void link(int x,int y){putroot(x);fa[x]=y;}
void cut(int x,int y){
putroot(x);
access(y);
splay(y);
son[y][0]=fa[x]=0;
pushup(y);
}
int query(int x,int y){
putroot(y);
access(x);
splay(x);
return siz[x]-1;
}
}lct;
int n,m,a[N];
int main(){
n=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++)
lct.link(i,(i+a[i]>n)?n+1:i+a[i]);
m=read();
for(int i=1;i<=m;i++){
int op,x,y;
scanf("%d",&op);
if(op==1){
scanf("%d",&x);x++;
printf("%d\n",lct.query(x,n+1));
}else{
scanf("%d%d",&x,&y);x++;
lct.cut(x,(x+a[x]>n)?n+1:x+a[x]);
a[x]=y;
lct.link(x,(x+a[x]>n)?n+1:x+a[x]);
}
}
return 0;
}
然后讲讲分块,每次暴力跳,维护一下每个点跳出当前块的操作次数,暴力修改暴力查询就好了
#include<bits/stdc++.h>
using namespace std;
#define INF 0x7fffffff
#define LL long long
#define N 1000010
const int siz=1000;
struct Temp{int to,tmp,bel;}a[N];
int n,m,pre[N];
int read(){
int ans=0,w=1;char c=getchar();
while(!isdigit(c)&&c!='-')c=getchar();
if(c=='-')c=getchar(),w=-1;
while(isdigit(c))ans=ans*10+c-'0',c=getchar();
return ans*w;
}
void modify(int x){
if(a[x+pre[x]].bel!=a[x].bel){
a[x].to=x+pre[x];
a[x].tmp=1;
}else{
a[x].to=a[x+pre[x]].to;
a[x].tmp=a[x+pre[x]].tmp+1;
}
return;
}
void build(){
for(int i=1;i<=n;i++)a[i].bel=(i-1)/siz+1;
for(int i=n;i>=1;i--)
if(i+pre[i]>n)a[i].tmp=1,a[i].to=0;
else modify(i);
}
int query(int x){
int ans=0;
while(x){
ans+=a[x].tmp;
x=a[x].to;
}
return ans;
}
int main(){
n=read();
for(int i=1;i<=n;i++)pre[i]=read();
build();
m=read();
for(int i=1;i<=m;i++){
int op=read(),x;
if(op==1){
x=read()+1;
printf("%d\n",query(x));
}else{
x=read()+1,pre[x]=read();
int fro=(a[x].bel-1)*siz+1;
for(int i=x;i>=fro;i--)modify(i);
}
}
return 0;
}
BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 【LCT】【分块】的更多相关文章
- [BZOJ2002] [Hnoi2010] Bounce 弹飞绵羊 (LCT)
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
- bzoj2002 [Hnoi2010]Bounce 弹飞绵羊【分块】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 这一题除了LCT解法,还有一种更巧妙,代码量更少的解法,就是分块.先想,如果仅仅记录每 ...
- [BZOJ2002][Hnoi2010]Bounce弹飞绵羊 LCT
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 建图,每次往后面跳就往目标位置连边,将跳出界的点设为同一个点.对于修改操作发现可以用 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 【分块】
任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 ...
- 2002: [Hnoi2010]Bounce 弹飞绵羊(分块)
2002: [Hnoi2010]Bounce 弹飞绵羊 时间限制: 10 Sec 内存限制: 259 MB 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他 ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT
2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...
- [bzoj2002][Hnoi2010]Bounce弹飞绵羊_LCT
Bounce弹飞绵羊 bzoj-2002 Hnoi-2010 题目大意:n个格子,每一个格子有一个弹簧,第i个格子会将经过的绵羊往后弹k[i]个,达到i+k[i].如果i+k[i]不存在,就表示这只绵 ...
- bzoj2002: [Hnoi2010]Bounce 弹飞绵羊 [分块][LCT]
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
- [bzoj2002][Hnoi2010]Bounce弹飞绵羊——分块
Brief description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装 ...
随机推荐
- sass的多种用法
sass的多种用法 主要归纳总结sass的常见用法,作为个人笔记使用,部分知识点并不仔细讲解.具体可参考文档:sass官网 一.嵌套 .svg{ position: absolute; left: 0 ...
- python+opencv+pyqt5控制摄像头在Qlabel上显示
import cv2 import numpy as numpy from PIL import * import sys from PyQt5.QtWidgets import * from PyQ ...
- offset的坑 使用前要将对象先show
使用jquery $('#obj').offset( {top:300, left: 600}); 如果设置offset之前是隐藏的,那么你设置新的offset之后就不会是指定的位置,而且会越飞越远, ...
- mysql术语
事务 概念:在关系数据库中,一个事物可以是一条sql语句,一组sql语句或整个程序. 特性:事物应该具有4个特性:原子性.一致性.隔离性.持久性.统称为ACID特性. 原子性(A)一个不可分割的工作单 ...
- npm install遇到的问题
phantomjs-prebuilt@2.1.16 install: 'node install.js' 在虚拟机上初始化vue-cli项目,npm install时遇到的问题 npm install ...
- eclipse安装插件:
eclipse安装插件:jre跟eclipse的bit数必须匹配,即必须都是32or64位的 历史版本不好找,pydev的历史版本在sourceforge中很隐蔽,得在项目的activite中查找,另 ...
- 数据存储-- Core Data的使用(二)
一.基础概念深入 1.NSManagedObjectContext 被管理数据上下文就像便笺簿 当从数据持久层获取数据时,相当于把这些临时的数据拷贝写在便笺簿上,然后就可以随心所欲的修改这些值. 通过 ...
- 给SqlParameter参数指定或不指定:@变量标识符的区别是什么?
对于sql语句中一个@的参数@au_id,在sqlParameter中,可以用@au_id,也可以用au_id. 要是bt点的,用两个@,你就不能随便省略@了. 对于sql语句 : select * ...
- Linux:declare命令详解
declare declare命令用于声明和显示已存在的shell变量.当不提供变量名参数时显示所有shell变量.declare命令若不带任何参数选项,则会显示所有shell变量及其值.declar ...
- 天气预报api整理
目录 1.国家气象局提供的天气预报接口 1.1.接口网址 1.2.示范代码 2.各个城市对应的代码 作为一个开发的diaosi,在开发过程中,时常会遇到添加天气的功能,现在百忙之中抽出一点时间整理了一 ...