Description

给 \(n\) 个点以及它们的弹力系数 \(k_i\) ,含义为 可以弹到 \(i + k_i\) 的位置。

支持两个东西,修改一个点的弹力系数;求一个点要弹多少次弹出 \(n\)

Solution

用 LCT 做。弹力系数是 \(k_i\) 可以看作是 \(i\) 和 \(i+k_i\) 连了一条边。如果弹出去了就不妨设和 \(0\) 连一条边。

对于修改操作,先把原来的边删除,修改 k 数组,再连上新边

对于查询操作,维护一个子树大小 siz (这里是 splay 上的 siz,不是原树上的),然后询问就相当于当前这个点 \(u\) 到 \(0\) 这条链上有几个点。所以就 split 出来这条链然后输出 siz - 1 就行了(注意要减 \(1\) 因为问的是弹多少次)

然后就做完了(注意输入的时候要加 1)

Code

#include <bits/stdc++.h>
using namespace std;
const int N = 200100;
int n, m, K[N];
struct node {
int siz, rev;
node *ch[2], *prt;
int dir() { return prt->ch[1] == this; }
int isr() { return !prt || (prt->ch[0] != this && prt->ch[1] != this); }
void setc(node *p, int k) { this->ch[k] = p; if(p) p->prt = this; }
void upd() { int s = 1; if(ch[0]) s += ch[0]->siz; if(ch[1]) s += ch[1]->siz; siz = s; }
void push() { if(!rev) return ; swap(ch[0], ch[1]);
if(ch[0]) ch[0]->rev ^= 1; if(ch[1]) ch[1]->rev ^= 1; rev = 0; }
}*P[N], pool[N], *cur = pool; node *sta[N]; int top;
node *New() { node *p = cur++; p->siz = 1; return p; }
void rotate(node *p) {
node *prt = p->prt; int k = p->dir();
if(!prt->isr()) prt->prt->setc(p, prt->dir());
else p->prt = prt->prt; prt->setc(p->ch[!k], k);
p->setc(prt, !k); prt->upd(); p->upd();
}
void splay(node *p) {
node *q = p;
while(1) { sta[++top] = q; if(q->isr()) break; q = q->prt; }
while(top) sta[top--]->push();
while(!p->isr()) {
if(p->prt->isr()) rotate(p);
else if(p->dir() == p->prt->dir()) rotate(p->prt), rotate(p);
else rotate(p), rotate(p);
} p->upd();
}
node *access(node *p) { node *q = 0; for(; p; p = p->prt) splay(p), p->ch[1] = q, (q = p)->upd(); return q; }
void mkroot(node *p) { access(p); splay(p); p->rev ^= 1; p->push(); }
void split (node *p, node *q) { mkroot(p); access(q); splay(p); }
void link (node *p, node *q) { mkroot(p); mkroot(q); p->setc(q, 1); }
void cut (node *p, node *q) { split(p, q); p->ch[1] = q->prt = 0; }
int main() {
scanf("%d", &n); P[0] = New();
for(int i = 1; i <= n; i++) scanf("%d", &K[i]), P[i] = New();
for(int i = 1; i <= n; i++) {
if(i + K[i] <= n) link(P[i], P[i + K[i]]);
else link(P[i], P[0]);
} int m; scanf("%d", &m);
for(int i = 1; i <= m; i++) {
int op, u; scanf("%d %d", &op, &u); u++;
if(op == 1) {
split(P[0], P[u]); printf("%d\n", P[0]->siz - 1);
}
if(op == 2) { int k; scanf("%d", &k);
if(u + K[u] <= n) cut(P[u], P[u + K[u]]);
else cut(P[u], P[0]); K[u] = k;
if(u + K[u] <= n) link(P[u], P[u + K[u]]);
else link(P[u], P[0]);
}
}
return 0;
}

题解【bzoj2002 [Hnoi2010]Bounce 弹飞绵羊】的更多相关文章

  1. BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 【LCT】【分块】

    BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始, ...

  2. [bzoj2002][Hnoi2010]Bounce弹飞绵羊_LCT

    Bounce弹飞绵羊 bzoj-2002 Hnoi-2010 题目大意:n个格子,每一个格子有一个弹簧,第i个格子会将经过的绵羊往后弹k[i]个,达到i+k[i].如果i+k[i]不存在,就表示这只绵 ...

  3. bzoj2002: [Hnoi2010]Bounce 弹飞绵羊 [分块][LCT]

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

  4. [BZOJ2002] [Hnoi2010] Bounce 弹飞绵羊 (LCT)

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

  5. [bzoj2002][Hnoi2010]Bounce弹飞绵羊——分块

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

  6. BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊(LCT)

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

  7. bzoj2002 [Hnoi2010]Bounce 弹飞绵羊——分块

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 第一次用分块,感觉超方便啊: 如果记录每个点的弹力系数,那么是O(1)修改O(n)查询 ...

  8. bzoj2002 [Hnoi2010]Bounce 弹飞绵羊【分块】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 这一题除了LCT解法,还有一种更巧妙,代码量更少的解法,就是分块.先想,如果仅仅记录每 ...

  9. 【lct】bzoj2002 [Hnoi2010]Bounce 弹飞绵羊

    lct板子,此题主要有cut操作和link操作. #include<cstdio> #include<iostream> #include<cstring> #in ...

随机推荐

  1. 常用DB2命令

    建库 db2 territory CN on 建库到指定位置 db2 create database OADB on D: using codeset GBK territory CN 列出所有数据库 ...

  2. (第十周)新NABCD

    项目名:食物链教学工具 组名:奋斗吧兄弟 组长:黄兴 组员:李俞寰.杜桥.栾骄阳.王东涵 新的NABCD模型: Need:可以辅助教师课堂讲授食物链相关的知识.软件的界面要漂亮,操作要简单,要给出软件 ...

  3. Daily Scrum8 11.12

    昨天的任务已完成. 今日任务: 徐钧鸿:个人作业 张艺:构建带有用户管理的框架,并将后端移植好的代码连结. 黄可嵩:完成搜索移植 徐方宇:研究httpclient如何运作,如何利用它实现服务器和客户端 ...

  4. 第三次实验报告 敏捷开发与XP实践

    一.  实验内容 (一)敏捷开发与XP 摘要:一项实践在XP环境中成功使用的依据通过XP的法则呈现,包括:快速反馈.假设简单性.递增更改.提倡更改.优质工作.XP软件开发的基石是XP的活动,包括:编码 ...

  5. 软工1816 · Beta冲刺(7/7)

    团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 协助完成安卓端的整合 完成安卓端的美化 协助制作宣传视频 接下来的计划 &am ...

  6. 第二次作业<2>

    自学计划 应为对网络的教程并不了解,所以-- 我扒了一遍同学的博客,找到了两个课程. 慕课网 和 这个. 选择这两个教程主要是深入浅出,比较合理. 开始先两个课程相互应证,多了解以后可能会选择一个.虽 ...

  7. HDU 3853 LOOPS 期望dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3853 LOOPS Time Limit: 15000/5000 MS (Java/Others)Me ...

  8. POJ 3597 Polygon Division 多边形剖分

    题目链接: http://poj.org/problem?id=3597 Polygon Division Time Limit: 2000MSMemory Limit: 131072K 问题描述 G ...

  9. 结对项目-四则运算出题程序(GUI版)

    目录: 一.致搭档(含项目地址) 二.PSP(planning) 三.结对编程中对接口的设计 四.计算模块接口的设计与实现过程 五.计算模块接口部分的性能改进 六.计算模块部分单元测试展示 七.计算模 ...

  10. 解决java使用Runtime.exec执行linux复杂命令不成功问题

    最近要实现一个Java调用一个复杂shell命令实现数据同步,该命令有管道重定向的语句,结果硬是执行不成功,而且也没异常报出.经过一段时间的折腾终于解决了此问题,权当做备忘记录下来(重点在红色框中的“ ...