【BZOJ2002】 [Hnoi2010]Bounce 弹飞绵羊
BZOJ2002 [Hnoi2010]Bounce 弹飞绵羊
Solution
很早以前写的一道分块题,最近在搞LCT,又做了一遍.
1.LCT做法
看到这种动态修改,想下LCT怎么维护.
修改操作就是\(Cut(x,k[x])\)然后再\(Link(x,k[x]')\)
剩下的只有询问了.
我们如果把弹出设为一个新节点\(n+1\),那么显然就是直接:
\(makeroot(x)\),\(access(n+1)\),\(splay(n+1)\).
最后答案就是\(siz[n+1].\)
2.分块做法
我们如果把编号分块,那么显然每一次修改就维护一下弹出的到了哪个块,然后随便搞一下就可以了.
代码实现
LCT
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
inline int gi()
{
int f=1,sum=0;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
const int N=300010;
int K[N],n;
struct node
{
int ff,ch[2],siz,rev;
}t[N];
int sta[N],top;
void pushup(int x)
{
t[x].siz=t[t[x].ch[0]].siz+t[t[x].ch[1]].siz+1;
}
void reverse(int x)
{
swap(t[x].ch[0],t[x].ch[1]);
t[x].rev^=1;
}
void pushdown(int x)
{
if(!t[x].rev)return;
if(t[x].ch[0])reverse(t[x].ch[0]);
if(t[x].ch[1])reverse(t[x].ch[1]);
t[x].rev^=1;
}
bool isroot(int x)
{
return (t[t[x].ff].ch[0]!=x) && (t[t[x].ff].ch[1]!=x);
}
void rotate(int x)
{
int y=t[x].ff,z=t[y].ff;
int k=t[y].ch[1]==x;
if(!isroot(y))t[z].ch[t[z].ch[1]==y]=x;//只能在这一棵Splay里面Rotate
t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1];
t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;t[y].ff=x;
pushup(y);pushup(x);
}
void splay(int x)
{
sta[++top]=x;
for(int i=x;!isroot(i);i=t[i].ff)sta[++top]=t[i].ff;
while(top)pushdown(sta[top--]);
while(!isroot(x))
{
int y=t[x].ff,z=t[y].ff;
if(!isroot(y))//Splay是旋转到当前这棵Splay的根,这个道理就和上面的rotate是一样的.
(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
rotate(x);
}
pushup(x);
}
void access(int x)
{
for(int y=0;x;y=x,x=t[x].ff)
{
splay(x);
t[x].ch[1]=y;
pushup(x);
}
}
void makeroot(int x)
{
access(x);splay(x);
reverse(x);
}
int findroot(int x)
{
access(x);splay(x);
while(t[x].ch[0])x=t[x].ch[0];
return x;
}
void split(int x,int y)
{
makeroot(x);
access(y);
splay(y);
}
void link(int x,int y)
{
makeroot(x);
t[x].ff=y;
}
void cut(int x,int y)
{
split(x,y);
t[y].ch[0]=t[x].ff=0;
}
int judge(int x)
{
return x>n?n+1:x;
}
int main()
{
n=gi();
for(int i=1;i<=n;i++)
t[i].siz=1;
for(int i=1;i<=n;i++)
link(i,judge(i+(K[i]=gi())));
int Q=gi();
while(Q--)
{
int opt=gi(),u=gi();u++;
if(opt==1)
{
makeroot(u);access(n+1);splay(n+1);
printf("%d\n",t[n+1].siz-1);
}
if(opt==2)
{
int tmp=K[u];
K[u]=gi();
cut(u,judge(u+tmp));
link(u,judge(u+K[u]));
}
}
return 0;
}
分块
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
inline int gi(){
int sum=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return f*sum;
}
const int N=400010;
int bl[N],nxt[N],sum[N],a[N];
int n,B,m;
void ask(int l,int r){
for(int i=r;i>=l;i--)
if(i+a[i]>min(n,bl[i]*B))sum[i]=1,nxt[i]=i+a[i];
else sum[i]=sum[i+a[i]]+1,nxt[i]=nxt[i+a[i]];
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
n=gi();B=sqrt(n);
for(int i=1;i<=n;i++)a[i]=gi();
for(int i=1;i<=n;i++)
bl[i]=(i-1)/B+1;
ask(1,n);
m=gi();int all=bl[n];
while(m--){
int opt=gi(),x=gi();x++;
if(opt==1){
int ans=sum[x],now=nxt[x],i=bl[x];
while(now<=n && i<=all){ans+=sum[now];now=nxt[now];i++;}
printf("%d\n",ans);
}
else{
int k=gi();
a[x]=k;
ask((bl[x]-1)*B+1,min(bl[x]*B,n));
}
}
return 0;
}
【BZOJ2002】 [Hnoi2010]Bounce 弹飞绵羊的更多相关文章
- BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 【LCT】【分块】
BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始, ...
- [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 弹飞绵羊 (LCT)
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...
- [bzoj2002][Hnoi2010]Bounce弹飞绵羊——分块
Brief description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装 ...
- BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊(LCT)
Description 某天,Lostmonkey发明了一种超级弹力装置,为了在 他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装 ...
- bzoj2002 [Hnoi2010]Bounce 弹飞绵羊——分块
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 第一次用分块,感觉超方便啊: 如果记录每个点的弹力系数,那么是O(1)修改O(n)查询 ...
- bzoj2002 [Hnoi2010]Bounce 弹飞绵羊【分块】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 这一题除了LCT解法,还有一种更巧妙,代码量更少的解法,就是分块.先想,如果仅仅记录每 ...
- 题解【bzoj2002 [Hnoi2010]Bounce 弹飞绵羊】
Description 给 \(n\) 个点以及它们的弹力系数 \(k_i\) ,含义为 可以弹到 \(i + k_i\) 的位置. 支持两个东西,修改一个点的弹力系数:求一个点要弹多少次弹出 \(n ...
- 【lct】bzoj2002 [Hnoi2010]Bounce 弹飞绵羊
lct板子,此题主要有cut操作和link操作. #include<cstdio> #include<iostream> #include<cstring> #in ...
随机推荐
- How to Create Triggers in MySQL
https://www.sitepoint.com/how-to-create-mysql-triggers/ I created two tables: CREATE TABLE `sw_user` ...
- 【Java】生成图形验证码
本章介绍一个能生成比较好看的图形验证码类 生成验证码工具类 package com.util; import java.awt.Color; import java.awt.Font; import ...
- 强连通缩点— HDU1827
强连通缩点以后最终形成的是一棵树 我们可以根据树的性质来看缩点以后的强连通分量图,就很好理解了 /* gyt Live up to every day */ #include<cstdio> ...
- Java学习总结1
1. 断点调试 a:定位(设置断点) b:启动调试 c:单步执行 观察变量(F5单步执行 F6单步跳过)d:修改2 static 静态 静态成员,为类的所有对象共享 在静态方法中,只能 ...
- mysql安装后初始密码
在安装过程中没有任何提示,安装完之后无法登陆 后经查询发现,可以暂时以 mysql -u root -p登陆 此账户没有密码直接enter即可. update user set Password=PA ...
- centos7 hdfs yarn spark 搭建笔记
1.搭建3台虚拟机 2.建立账户及信任关系 3.安装java wget jdk-xxx rpm -i jdk-xxx 4.添加环境变量(全部) export JAVA_HOME=/usr/java/j ...
- windows mysql绿色版配置
MySQL绿色版安装 1.下载地址 https://dev.mysql.com/downloads/mysql/ 2.配置my.ini 文件 解压下载文件到指定目录.如: my.ini文件内容: [m ...
- PCA图
R语言PCA 1.关键点 综述:主成分分析 因子分析 典型相关分析,三种方法的共同点主要是用来对数据降维处理的从数据中提取某些公共部分,然后对这些公共部分进行分析和处理. #主成分分析 是将多指标化为 ...
- 文字过多以省略号代替,放在文字上会显示title信息提示
第一种: <td style="text-align:left; word-wrap:break-word;" title="${b.remarks}"& ...
- 在vue中使用后台提供 的token验证方式总结及使用方法
token是相对会叫安全的使用暗码形式的数据传输,由后台产生,并且传输到前台,前台可以将保存,在前台每次发送请求的时候可以携带token,后台可以对token进行验证,通过验证的通过请求可以对数据进行 ...