要维护深度,就维护一下size就行了.access一下x,那么从根->x这一条链就独立成为一棵splay,那么splay的size节点数就是x的深度.

删边的时候直接access一下,splay一下,那么在原树中的父亲就是自己的右儿子,断掉那条边,再upd即可.

CODE

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
template<typename T>inline void read(T &num) {
char ch; int flg = 1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flg=-flg;
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
num*=flg;
}
const int MAXN = 200005;
int n, q;
namespace LCT {
#define ls ch[x][0]
#define rs ch[x][1]
int ch[MAXN][2], fa[MAXN], sz[MAXN];
bool rev[MAXN];
inline bool isr(int x) { return ch[fa[x]][0] != x && ch[fa[x]][1] != x; }
inline bool get(int x) { return x == ch[fa[x]][1]; }
inline void upd(int x) {
sz[x] = sz[ls] + sz[rs] + 1;
}
inline void rot(int x) {
int y = fa[x], z = fa[y], l = get(x), r = l^1;
if(!isr(y)) ch[z][get(y)] = x;
fa[ch[x][r]] = y; fa[y] = x; fa[x] = z;
ch[y][l] = ch[x][r]; ch[x][r] = y;
upd(y), upd(x);
}
inline void mt(int x) { if(rev[x]) rev[x] ^= 1, rev[ls] ^= 1, rev[rs] ^= 1, swap(ls, rs); }
void mtpath(int x) { if(!isr(x)) mtpath(fa[x]); mt(x); }
inline void splay(int x) {
mtpath(x);
for(; !isr(x); rot(x))
if(!isr(fa[x])) rot(get(x)==get(fa[x])?fa[x]:x);
}
inline int access(int x) { int y=0;
for(; x; x=fa[y=x]) splay(x), ch[x][1]=y, upd(x);
return y;
}
inline void bert(int x) { access(x), splay(x), rev[x] ^= 1; }
inline int sert(int x) {
access(x), splay(x);
for(; ch[x][0]; x=ch[x][0]);
return x;
}
inline void link(int x, int y) {
bert(x);
if(sert(y) == x) return;
fa[x] = y;
}
inline void cut(int x, int y) {
bert(x), access(y), splay(y);
if(sert(y) != x || fa[x] != y || ch[x][1] != 0) return;
fa[x] = ch[y][0] = 0; upd(y);
}
inline void modify(int x, int val) {
access(x), splay(x);
ch[x][0] = fa[ch[x][0]] = 0; upd(x);
if(x + val <= n) link(x, x+val);
}
inline int split(int x, int y) {
bert(x), access(y), splay(y);
return y;
}
inline int querysz(int x) {
access(x), splay(x);
return sz[x];
}
}
using namespace LCT;
int main () {
read(n);
for(int i = 1, k; i <= n; ++i) {
read(k);
if(i+k <= n) link(i, i+k);
}
read(q);
int opt, x, y;
while(q--) {
read(opt), read(x); ++x;
if(opt == 1) printf("%d\n", querysz(x));
else read(y), modify(x, y);
}
}

最新文章

  1. ASP.NET Core Docker部署
  2. [bigdata] Spark RDD整理
  3. SpringMvc 页面DATE传值问题
  4. android studio入门
  5. LeetCode 287
  6. 上海Uber优步司机奖励政策(2月1日~2月7日)
  7. jps查看java进程中哪个线程在消耗系统资源
  8. 返璞归真 asp.net mvc (2) - 路由(System.Web.Routing)
  9. [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)
  10. html代替submit按钮的图片代码
  11. 第二期培训(PING问题定位指导)心得
  12. 【Android Widget】FragmentTabHost
  13. 201521123076 《Java程序设计》第7周学习总结
  14. linux shell中获取mongodb最大连接数、内存使用情况等
  15. python练习题目
  16. python dict to dataframe
  17. 【转】shell之for、while、until循环
  18. CUDA编程之快速入门
  19. 微服务的发现与注册--Eureka
  20. Hive 的排名和跨行 窗口函数及其使用

热门文章

  1. 在UPW中使用VLC解码媒体
  2. [百家号]7nm ARM 64核!华为Hi1620高性能CPU公开:3.0GHz
  3. SQL SERVER YEAR函数
  4. 使用pycharm开发web——django2.1.5(三)创建models并进入交互界面shell做一些简单操作
  5. 异常处理 try
  6. Python--类的调用
  7. javascript 仿jQuery的无new构造函数
  8. docker 入门2 - 容器 【翻译】
  9. mybatis的BLOB存储与读取
  10. Lua虚拟机中的数据结构与栈