上一次用分块过了, 今天换了一种lct(link-cut tree)的写法。

学lct之前要先学过splay。

lct 简单的来说就是 一颗树, 然后每次起作用的都是其中的某一条链。

所以每次如果需要用到一条链, 就要先 access 一下某个位置, 到root, 将其他的非法的东西抠掉。

并且 一个很大的特点就是  假设现在有u,v2个节点, 存在一条边 u -> v, 那么 u 的 父亲指向 v 但是 v 不一定存在 儿子节点指向 u , 也就是说很多时候是单向边。

然后对于整个lct来说, 他由很多个splay组成的。

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
  4. #define LL long long
  5. #define ULL unsigned LL
  6. #define fi first
  7. #define se second
  8. #define pb push_back
  9. #define lson l,m,rt<<1
  10. #define rson m+1,r,rt<<1|1
  11. #define lch tr[x].son[0]
  12. #define rch tr[x].son[1]
  13. #define max3(a,b,c) max(a,max(b,c))
  14. #define min3(a,b,c) min(a,min(b,c))
  15. typedef pair<int,int> pll;
  16. const int inf = 0x3f3f3f3f;
  17. const LL INF = 0x3f3f3f3f3f3f3f3f;
  18. const LL mod = (int)1e9+;
  19. const int N = 2e5 + ;
  20. int n, t;
  21. struct Node{
  22. int son[], pre;
  23. int sz, is_root;
  24. inline void init() {
  25. son[] = son[] = pre = ;
  26. sz = is_root =;
  27. }
  28. }tr[N];
  29. void Push_Up(int x){
  30. if(!x) return ;
  31. tr[x].sz = tr[lch].sz + tr[rch].sz + ;
  32. }
  33. void rotate(int x){
  34. if(tr[x].is_root) return ;
  35. int y = tr[x].pre, z = tr[y].pre;
  36. int k = x == tr[y].son[];
  37. tr[y].son[k] = tr[x].son[k^];
  38. tr[tr[y].son[k]].pre = y;
  39. tr[x].son[k^] = y;
  40. tr[y].pre = x;
  41. tr[x].pre = z;
  42. if(tr[y].is_root) tr[x].is_root = , tr[y].is_root = ;
  43. else tr[z].son[ tr[z].son[] == y] = x;
  44. Push_Up(y);
  45.  
  46. }
  47. void Splay(int x){
  48. while(!tr[x].is_root){
  49. int y = tr[x].pre, z = tr[y].pre;
  50. if(!tr[y].is_root){
  51. if((y == tr[z].son[]) != ( x == tr[y].son[])) rotate(y);
  52. else rotate(x);
  53. }
  54. rotate(x);
  55. }
  56. Push_Up(x);
  57. }
  58. void access(int x){
  59. int y = ;
  60. do{
  61. Splay(x);
  62. tr[rch].is_root = ;
  63. rch = y;
  64. tr[rch].is_root = ;
  65. Push_Up(x);
  66. y = x;
  67. x = tr[x].pre;
  68. }while(x);
  69. }
  70. inline void link(int u, int v){
  71. if(v > n) v = ;
  72. tr[u].pre = v;
  73. }
  74. inline void cut(int x){
  75. access(x);
  76. Splay(x);
  77. tr[lch].is_root = ;
  78. tr[lch].pre = ;
  79. lch = ;
  80. Push_Up(x);
  81. }
  82. inline int Query(int x){
  83. access(x);
  84. Splay(x);
  85. return tr[lch].sz + ;
  86. }
  87. int main(){
  88. scanf("%d", &n);
  89. for(int i = ; i <= n; i++) tr[i].init();
  90. for(int i = ; i <= n; i++){
  91. scanf("%d", &t);
  92. link(i, t+i);
  93. }
  94. int m, op, x, k;
  95. scanf("%d", &m);
  96. while(m--){
  97. scanf("%d", &op);
  98. if(op == ) {
  99. scanf("%d", &x);
  100. printf("%d\n", Query(x+));
  101. }
  102. else {
  103. scanf("%d%d", &x, &k);
  104. cut(x+);
  105. link(x+, x+k+);
  106. }
  107. }
  108. return ;
  109. }

bzoj 2002 弹飞绵羊 lct裸题的更多相关文章

  1. [bzoj] 2002 弹飞绵羊 || LCT

    原题 简单的LCT练习题. 我们发现对于一个位置x,他只能跳到位置x+k,也就是唯一的父亲去.加入我们将弹飞的绵羊定义为跳到了n+1,那么这就形成了一棵树.而因为要修改k,所以这颗树是动态连边的,那么 ...

  2. BZOJ 2002 弹飞绵羊(分块)

    题目:弹飞绵羊 这道题,据说是lct裸题,但是lct那么高级的数据结构,我并不会,所以采取了学长讲过的分块做法,我们对序列分块,可以定义两个数组,其中一个表示从当前位置跳出当前块需要多少步,另一个数组 ...

  3. bzoj 2002: 弹飞绵羊 Link-Cut-Tree

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

  4. BZOJ 2002 弹飞绵羊

    LCT 刚学LCT,对LCT的性质不太熟练,还需要多多练习.. 对每一个点,将其与它能够到达的点连一条虚边.弹出去的话就用n+1这个节点表示. 第一种操作我们需要从LCT的性质入手,问的问题其实就是x ...

  5. bzoj 2002 弹飞绵羊 分块

    正解lct,然而本蒟蒻并不会.... 分块思路很清晰,处理出每个点弹出所在块所需要的步数及出去后的第一个位置 #include<cstdio> #include<cstring> ...

  6. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...

  7. [Luogu P3203] [HNOI2010]弹飞绵羊 (LCT维护链的长度)

    题面 传送门:洛谷 Solution 这题其实是有类似模型的. 我们先考虑不修改怎么写.考虑这样做:每个点向它跳到的点连一条边,最后肯定会连成一颗以n+1为根的树(我们拿n+1代表被弹出去了).题目所 ...

  8. 洛谷P3203 [HNOI2010] 弹飞绵羊 [LCT]

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

  9. P3203 [HNOI2010]弹飞绵羊(LCT)

    弹飞绵羊 题目传送门 解题思路 LCT. 将每个节点的权值设为\(1\),连接\(i\)和\(i+ki\),被弹飞就连上\(n\),维护权值和\(sum[]\).从\(j\)弹飞需要的次数就是\(sp ...

随机推荐

  1. springBoot的过滤器,监听器,拦截器

    概述 在开发中,我们经常要考虑一些问题,对敏感词进行过滤,用户是否已经登录,是否需要对他的请求进行拦截,或者领导问现在在线人数有多少人?我们如何实现这些功能哪 @WebFilter package c ...

  2. Consul和Kong的实践(一)

    Consul和Kong的实践(一) 这一篇先介绍consul集群,以及consul和应用服务的结合使用,下一篇是和kong网关的结合. 一.Consul的集群安装 以其中一台机器为例: mkdir / ...

  3. go 学习笔记之工作空间

    搭建好 Go 的基本环境后,现在可以正式开始 Go 语言的学习之旅,初学时建议在默认的 GOPATH 工作空间规范编写代码,基本目录结构大概是这个样子. . |-- bin | `-- hello.e ...

  4. 如何在Vue项目中使用vw实现移动端适配

    有关于移动端的适配布局一直以来都是众说纷纭,对应的解决方案也是有很多种.在< 使用Flexible实现手淘H5页面的终端适配>提出了Flexible的布局方案,随着 viewport 单位 ...

  5. TensorFlow学习笔记——深层神经网络的整理

    维基百科对深度学习的精确定义为“一类通过多层非线性变换对高复杂性数据建模算法的合集”.因为深层神经网络是实现“多层非线性变换”最常用的一种方法,所以在实际中可以认为深度学习就是深度神经网络的代名词.从 ...

  6. Linux基础进程管理

    一.进程 了解如进程的: • PID,PPID • 当前的进程状态 • 内存的分配情况 • CPU和已花费的实际时间 • 用户UID,他决定进程的特权 (一).静态查看进程 # ps axu | le ...

  7. jQuery插件之路(三)——文件上传(支持拖拽上传)

    好了,这次咱一改往日的作风,就不多说废话了,哈哈.先贴上源代码地址,点击获取.然后直接进入主题啦,当然,如果你觉得我有哪里写的不对或者欠妥的地方,欢迎留言指出.在附上一些代码之前,我们还是先来了解下, ...

  8. SonarQube系列一、Linux安装与部署

    [前言] 随着项目团队规模日益壮大,项目代码量也越来越多.且不说团队成员编码水平层次不齐,即便是老手,也难免因为代码量的增加和任务的繁重而忽略代码的质量,最终的问题便是bug的增多和代码债务的堆积.因 ...

  9. python小白手册之字符串的私有方法和公用方法

    #字符串方法. name=input('1111') if name.isalnum(): print(是否由数字字母) isdigit isdecimal判断数字 strip去空格或者其他 name ...

  10. 谨慎 mongodb 关于数字操作可能导致类型及精度变化

    1.问题描述 最近有一个需求,更新Mongo数据库中 原料 集合的某字段价格,更新后,程序报错了,说长度过长了,需要Truncation. 主要错误信息如下: FormatException: An ...