【bzoj2002】 [Hnoi2010]Bounce 弹飞绵羊
2015-09-27 13:43
302 查看
非常裸的裸题……
很明显每个点跳到的点的编号一定大于当前点,那么整个跳的图就形成了一个树结构,每个点的父亲节点定义为min(i+k,n)
这样搞之后,操作1就是查询某个点的深度,操作2就是换父亲
大概可以用dfs序搞
/∗/*这个坑以后再填好了∗/*/
反正只有换父亲嘛。。。来发lct就好啦2333
作死地写了单旋然后T掉了= =
很明显每个点跳到的点的编号一定大于当前点,那么整个跳的图就形成了一个树结构,每个点的父亲节点定义为min(i+k,n)
这样搞之后,操作1就是查询某个点的深度,操作2就是换父亲
大概可以用dfs序搞
/∗/*这个坑以后再填好了∗/*/
反正只有换父亲嘛。。。来发lct就好啦2333
作死地写了单旋然后T掉了= =
[code]#include <bits/stdc++.h> using namespace std; #define For(i,a,b) for(int i=a;i<b;i++) #define lc ch[u][0] #define rc ch[u][1] #define maxn 200003 inline int rd() { char c = getchar(); while (!isdigit(c)) c = getchar() ; int x = c - '0'; while (isdigit(c = getchar())) x = x * 10 + c - '0'; return x; } typedef int arr[maxn]; arr fa , size , rv , sta; int ch[maxn][2] , top , n , m; inline bool isrt(int u) { return (ch[fa[u]][0] != u) && (ch[fa[u]][1] != u) ; } inline void mt(int u) { if (u) size[u] = 1 + (lc ? size[lc] : 0) + (rc ? size[rc] : 0) ; } inline void ps(int u) { if (u && rv[u]) swap(lc , rc) , rv[lc] ^= 1 , rv[rc] ^= 1 , rv[u] = 0; } inline void rot(int u) { int f = fa[u] , g = fa[f] , l , r; l = (ch[f][1] == u) , r = l ^ 1; if (!isrt(f)) ch[g][ch[g][1] == f] = u; fa[u] = g , fa[f] = u;if (ch[u][r]) fa[ch[u][r]] = f; ch[f][l] = ch[u][r] , ch[u][r] = f; mt(f) , mt(u); } inline void clear(int u) { for(sta[top ++] = u;!isrt(u);u = fa[u]) sta[top ++] = fa[u]; for(;top;) ps(sta[-- top]); } inline void splay(int u) { for(clear(u);!isrt(u);rot(u)) { int f = fa[u] , g = fa[f]; if (!isrt(f)) rot(((ch[f][1] == u) ^ (ch[g][1] == f)) ? u : f); } mt(u); } inline void access(int u) { int v = u; for(int t = 0;u;t = u , u = fa[u]) splay(u) , rc = t ; splay(v); } inline void mkrt(int u) { access(u) ; rv[u] ^= 1 ; ps(u) ; } inline void link(int u , int v) { mkrt(u) , fa[u] = v ; } inline void cut(int u) { mkrt(n + 1); access(u); fa[lc] = 0 , lc = 0 , mt(u); } inline int get_dep(int u) { mkrt(u); access(n + 1); return size[n + 1] - 1; } inline int get_par(int u , int k) { u += k ; if (u > n) u = n + 1 ; return u ; } int main() { #ifndef ONLINE_JUDGE freopen("data.txt" , "r" , stdin); freopen("data.out" , "w" , stdout); #endif n = rd(); For(i , 1 , n + 1) link(i , get_par(i , rd())); m = rd(); For(i , 0 , m) { int a = rd() , b = rd() + 1 , c; if (a == 2) { c = rd(); cut(b); link(b , get_par(b , c)); } else printf("%d\n" , get_dep(b)); } return 0; }
相关文章推荐
- SQL数据库
- 自定义控件(视图)28期笔记05:自定义控件之继承自View(滑动开关)
- bfc ifc
- C语言程序初体验-第十一课-第五题:角度转换
- 数据解析/网络编程/图片异步下载KVO/初级数据持久化
- eclipse常用的几个快捷键
- 2016年一些面试题的整理和心情--1异或到100
- 第一个PHP程序——Hello World
- DFS:Curling 2.0(POJ 3009)
- 日经春秋 20150927
- [LeetCode] Unique Binary Search Trees(!!DP)
- x264 - open gop and closed gop
- Windows下一个AndroidStudio 正在使用Git(AndroidStudio工程GitHub关联)
- MacBook Pro 的照相机在哪?
- spring_150910_hibernate_id_auto
- 最短路spfaPOJInvitation Cardsj解题报告
- 软件工程
- 【c++ templates读书笔记】【4】技巧性基础知识
- 【c++ templates读书笔记】【4】技巧性基础知识
- socket编程发送GET请求