link-cut tree

#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
const int N = 5e5 + ;
struct Node{
int rev, rt;
int son[], pre;
int mx, val, id;
void init(){
rt = ; rev = pre = son[] = son[] = ;
mx = val = id = ;
}
}tr[N];
void Push_Rev(int x){
if(!x) return ;
swap(lch(x), rch(x));
tr[x].rev ^= ;
}
void Push_Up(int x){
if(!x) return ;
tr[x].mx = tr[x].val, tr[x].id = x;
if(tr[x].mx < tr[lch(x)].mx) tr[x].mx = tr[lch(x)].mx, tr[x].id = tr[lch(x)].id;
if(tr[x].mx < tr[rch(x)].mx) tr[x].mx = tr[rch(x)].mx, tr[x].id = tr[rch(x)].id;
}
void Push_Down(int x){
if(tr[x].rev){
tr[x].rev = ;
Push_Rev(lch(x));
Push_Rev(rch(x));
}
}
void Rev(int x){
if(!tr[x].rt) Rev(tr[x].pre);
Push_Down(x);
}
void rotate(int x){
if(tr[x].rt) return;
int y = tr[x].pre, z = tr[y].pre;
int k = (rch(y) == x);
tr[y].son[k] = tr[x].son[k^];
tr[tr[y].son[k]].pre = y;
tr[x].son[k^] = y;
tr[y].pre = x;
tr[x].pre = z;
if(tr[y].rt) tr[y].rt = , tr[x].rt = ;
else tr[z].son[rch(z) == y] = x;
Push_Up(y);
}
void Splay(int x){
Rev(x);
while(!tr[x].rt){
int y = tr[x].pre, z = tr[y].pre;
if(!tr[y].rt){
if(( x == rch(y) ) != (y == rch(z))) rotate(x);
else rotate(y);
}
rotate(x);
}
Push_Up(x);
}
void Access(int x){
int y = ;
do{
Splay(x);
tr[rch(x)].rt = ;
rch(x) = y;
tr[y].rt = ;
Push_Up(x);
y = x;
x = tr[x].pre;
}while(x);
}
void Make_rt(int x){
Access(x);
Splay(x);
Push_Rev(x);
}
bool judge(int u, int v){
while(tr[u].pre) u = tr[u].pre;
while(tr[v].pre) v = tr[v].pre;
return u == v;
}
void link(int u, int v){
Make_rt(u);
tr[u].pre = v;
}
void cut(int u, int v){
Make_rt(u);
Access(v);
Splay(v);
tr[lch(v)].pre = ;
tr[lch(v)].rt = ;
tr[v].pre = ;
lch(v) = ;
}

维护子树。

维护子树就是新开一个状态存一下 所有非偏爱子节点的信息, 然后每次access的时候我们就根据偏爱子节点的变化, 从而更新这个新开的状态。

这个写法 是维护 子树内的亦或和。

代码:

#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
const int N = 5e5 + ;
struct Node{
int rev, rt;
int son[], pre;
int sum, vsum, key;
void init(){
rt = ; rev = pre = son[] = son[] = ;
sum = vsum = key = ;
}
}tr[N];
void Push_Rev(int x){
if(!x) return ;
swap(lch(x), rch(x));
tr[x].rev ^= ;
}
void Push_Up(int x){
if(!x) return ;
tr[x].sum = tr[x].key ^ tr[lch(x)].sum ^ tr[rch(x)].sum ^ tr[x].vsum;
}
void Push_Down(int x){
if(tr[x].rev){
tr[x].rev = ;
Push_Rev(lch(x));
Push_Rev(rch(x));
}
}
void Rev(int x){
if(!tr[x].rt) Rev(tr[x].pre);
Push_Down(x);
}
void rotate(int x){
if(tr[x].rt) return;
int y = tr[x].pre, z = tr[y].pre;
int k = (rch(y) == x);
tr[y].son[k] = tr[x].son[k^];
tr[tr[y].son[k]].pre = y;
tr[x].son[k^] = y;
tr[y].pre = x;
tr[x].pre = z;
if(tr[y].rt) tr[y].rt = , tr[x].rt = ;
else tr[z].son[rch(z) == y] = x;
Push_Up(y);
}
void Splay(int x){
Rev(x);
while(!tr[x].rt){
int y = tr[x].pre, z = tr[y].pre;
if(!tr[y].rt){
if(( x == rch(y) ) != (y == rch(z))) rotate(x);
else rotate(y);
}
rotate(x);
}
Push_Up(x);
}
void Access(int x){
int y = ;
do{
Splay(x);
tr[rch(x)].rt = ;
tr[x].vsum ^= tr[rch(x)].sum;
rch(x) = y;
tr[x].vsum ^= tr[rch(x)].sum;
tr[y].rt = ;
Push_Up(x);
y = x;
x = tr[x].pre;
}while(x);
}
void Make_rt(int x){
Access(x);
Splay(x);
Push_Rev(x);
}
void link(int u, int v){
Make_rt(u);
Access(v);
Splay(v);
tr[u].pre = v;
tr[v].
vsum ^= tr[u].sum;
Push_Up(v);
}
void cut(int u, int v){
Make_rt(u);
Access(v);
Splay(v);
tr[lch(v)].pre = ;
tr[lch(v)].rt = ;
tr[v].pre = ;
lch(v) = ;
Push_Up(v);
}

最新文章

  1. Join 和 apply 用法
  2. JS组件系列——Bootstrap右键菜单解决方案:ContextMenu
  3. linux下 html转pdf
  4. 【MySQL】MySQL 如何实现 唯一随机数ID
  5. BZOJ 1797 最小割
  6. pthread_key_t和pthread_key_create()详解
  7. SQL-LINQ-Lambda语法对照
  8. B - Maya Calendar(第二季水)
  9. HTML 总结-表单-表单属性
  10. Java经典23创意模式设计模式(两)
  11. 201521123004 《Java程序设计》第7周学习总结
  12. 正则表达式&amp;常用JS校验
  13. java.net.BindException: Cannot assign requested address: bind
  14. 2017ecjtu-summer training # 11 POJ 2492
  15. Myeclipse插件快速生成ssh项目并配置注解 在action层注入service的超详细过程
  16. 二十六、css3改变checkbox复选框的样式
  17. 013-mac重做系统后的软件安装
  18. LinkedBlockingQueue源码分析
  19. 2018-04-11 activity周期
  20. Linux下双网卡绑定bond0【转】

热门文章

  1. UIRefreshControl 问题
  2. 常用GDB命令行调试命令
  3. angular6组件封装以及发布到npm
  4. 解决微信小程序开发者工具输入框焦点问题
  5. 还在为垂直居中苦恼?CSS 布局利器 flexbox 轻轻松松帮你搞定
  6. 使用bibtex为latex论文添加参考文献
  7. Kafka 0.8 Producer (0.9以前版本适用)
  8. Android UI控件常用库汇总
  9. 关于sparksql中设置自定义自增列的相关要点(工作共踩过的坑-1)
  10. Ubuntu系统开发环境完整搭建