LinkCutTree 总结

 

最近学习了LinkCutTree,总结一下。

LinkCutTree是一种数据结构(是Tree Decomposition中的一种),她维护的一般是无向图(一个森林),支持连边、删边、链修改、链查询(点属于特殊的链,修改可以是单点修改、整链修改,查询可以是最值、和等)这四种操作。

中心思想是将边分类,一类边组成一些连续的链,每条链保存在一颗BST中(一般是Splay),BST中以点到根的距离为关键字(左边的点是右边的点的祖先),其它一些边连接这些链。(LinkCutTree是树链剖分(又叫轻重链剖分)的动态版本,并且更灵活),可以证明,LinkCutTree的各种操作都是均摊O(logn)的(渐进复杂度比树链剖分的O(log^2)还好,但是常数巨大,所以实测一般时间是树链剖分的1.5~2倍)。

上面的“链修改、链查询”指的是链上的点,如果要将对象改为边,可以为每条边建立一个边点,即若存在边(u,v),则新加一个点z代表边,将z连接u和v,z的点权就是(u,v)的边权,非边点的权设为-oo),然后对边权的统计就变成了对点权的统计(这是LCT中处理边信息的通法之一)。

 

  1 #include <cstdio>
  2 #include <iostream>
  3 #define maxn 10010
  4 using namespace std;
  5 
  6 /*
  7 我的代码风格:用数组模拟指针和结构体。
  8 变量含义:
  9 pnt[u] - path-parent of u in the tree
 10 pre[u] - the father of u in the Splay
 11 son[u][0] - the left child of u in the Splay
 12 son[u][1] - the right child of u in the Splay
 13 val[u] - the weight of u
 14 sum[u] - the sum of weight of all the nodes in the subtree of u
 15 siz[u] - the number of the nodes in the subtree of u
 16 itg[u] - increasement tag ( the lazy tag )
 17 rtg[u] - rotate tag ( the lazy tag )
 18  */
 19 /*
 20 模板功能:支持删边和连边,支持将一条链的点权做一个增量,支持查询一条链的点权和,判断两点是否再同一联通块中
 21 因为是自己想的一个功能,所以没有地方交,不保证代码正确性。(重在理解)
 22 代码中哪里不懂欢迎回复,代码丑别喷。
 23 */
 24 namespace L {
 25     int pnt[maxn], pre[maxn], son[maxn][2], val[maxn], 
 26         sum[maxn], siz[maxn], itg[maxn], rtg[maxn];
 27 
 28     void update( int nd ) {
 29         sum[nd] = val[nd] + sum[son[nd][0]] + sum[son[nd][1]];
 30     }
 31     void rotate( int nd, int d ) {
 32         int p = pre[nd];
 33         int s = son[nd][!d];
 34         int ss = son[s][d];
 35 
 36         son[nd][!d] = ss;
 37         son[s][d] = nd;
 38         if( p ) son[p][ nd==son[p][1] ] = s;
 39         else pnt[s] = pnt[nd];
 40 
 41         pre[nd] = s;
 42         pre[s] = p;
 43         pre[ss] = nd;
 44 
 45         update( nd );
 46         update( s );
 47     }
 48     void pushdown( int nd ) {
 49         if( rtg[nd] ) {
 50             int &ls = son[nd][0], &rs = son[nd][1];
 51             swap(ls,rs);
 52             rtg[ls] ^= 1;
 53             rtg[rs] ^= 1;
 54             rtg[nd] = 0;
 55         }
 56         if( itg[nd] ) {
 57             int ls = son[nd][0], rs = son[nd][1];
 58             int delta = itg[nd];
 59             itg[ls] += delta;
 60             itg[rs] += delta;
 61             val[ls] += delta;
 62             val[rs] += delta;
 63             sum[ls] += siz[ls]*delta;
 64             sum[rs] += siz[rs]*delta;
 65             itg[nd] = 0;
 66         }
 67     }
 68     void big_push( int nd ) {
 69         if( pre[nd] ) big_push(pre[nd]);
 70         pushdown(nd);
 71     }
 72     void splay( int nd, int top=0 ) {
 73         big_push(nd);
 74         while( pre[nd]!=top ) {
 75             int p = pre[nd];
 76             int nl = nd==son[p][0];
 77             if( pre[p]==top ) {
 78                 rotate( p, nl );
 79             } else {
 80                 int pp = pre[p];
 81                 int pl = p==son[pp][0];
 82                 if( nl==pl ) {
 83                     rotate( pp, pl );
 84                     rotate( p, nl );
 85                 } else {
 86                     rotate( p, nl );
 87                     rotate( pp, pl );
 88                 }
 89             }
 90         }
 91     }
 92     void access( int nd ) {
 93         int u = nd;
 94         int v = 0;
 95         while( u ) {
 96             splay( u );
 97             int s = son[u][1];
 98             pre[s] = 0;
 99             pnt[s] = u;
100             pre[v] = u;
101             son[u][1] = v;
102             update( u );
103             v = u;
104             u = pnt[u];
105         }
106         splay( nd );
107     }
108     int findroot( int nd ) {
109         while( pre[nd] ) nd=pre[nd];
110         while( pnt[nd] ) {
111             nd = pnt[nd];
112             while( pre[nd] ) nd=pre[nd];
113         }
114         return nd;
115     }
116     void makeroot( int nd ) {
117         access( nd );
118         rtg[nd] ^= 1;
119     }
120     bool sameroot( int u, int v ) {
121         return findroot(u)==findroot(v);
122     }
123     void link( int u, int v  ){
124         makeroot(u);
125         makeroot(v);
126         pnt[u] = v;
127     }
128     void cut( int u, int v ) {
129         makeroot(u);
130         access(v);
131         pnt[u] = 0;
132         pre[u] = 0;
133         son[v][0] = 0;
134         update( v );
135     }
136     void up_val( int u, int v, int delta ) {
137         makeroot(u);
138         access(v);
139         val[v] += delta;
140         sum[v] += siz[v]*delta;
141         itg[v] += delta;
142     }
143     int qu_sum( int u, int v ) {
144         makeroot(u);
145         access(v);
146         return val[v]+sum[son[v][0]];
147     }
148 };
149 /*
150 int main() {
151     L::link(1,2);
152     L::link(2,3);
153     L::link(3,4);
154     L::up_val(1,3,3);
155     L::up_val(2,4,-3);
156     printf( "%d\n", L::qu_sum(1,1) );
157     printf( "%d\n", L::qu_sum(2,2) );
158     printf( "%d\n", L::qu_sum(3,3) );
159     printf( "%d\n", L::qu_sum(4,4) );
160     printf( "%d\n", L::qu_sum(2,3) );
161 }
162 */
163 int main() {
164     L::link(1,2);
165     L::link(2,3);
166     L::link(3,4);
167     L::up_val( 1, 4, 5 );
168     L::cut(2,3);
169     printf( "%d\n", L::qu_sum(1,2) );
170     printf( "%d\n", L::qu_sum(3,4) );
171     printf( "%d\n", L::sameroot(2,3) );
172 }
View Code


推荐学习资料:

杨思雨 《伸展树的基本操作与应用》

杨哲 《QTREE解法的一些研究》

http://blog.csdn.net/d891320478/article/details/9181385

 

转载于:https://www.cnblogs.com/idy002/p/4292283.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/273389.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows中安装zookeeper

Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目&#xff0c;它主要是用来解决分布式应用中经常遇到的一些数据管理问题&#xff0c;如&#xff1a;统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。本文将从使用者角度详细介绍 Zookeeper 的安装和配…

【编程练习】正整数分解为几个连续自然数之和

题目&#xff1a;输入一个正整数&#xff0c;若该数能用几个连续正整数之和表示&#xff0c;则输出所有可能的正整数序列。 一个正整数有可能可以被表示为n(n>2)个连续正整数之和&#xff0c;如&#xff1a; 1512345 15456 1578 有些数可以写成连续N&#xff08;>1&am…

IOS-C语言第12天,(函数指针)Point and macro(宏)

转载于:https://www.cnblogs.com/xiangrongsu/p/4309366.html

Apache POI使用详解

1.POI结构与常用类(1)POI介绍Apache POI是Apache软件基金会的开源项目&#xff0c;POI提供API给Java程序对Microsoft Office格式档案读和写的功能。 .NET的开发人员则可以利用NPOI (POI for .NET) 来存取 Microsoft Office文档的功能。(2)POI结构说明包名称 说明HSSF 提供读写M…

Http协议(3)—HTTP实体和编码

HTTP实体实现目标.可以被正确识别(通过Content-Type和Content-Launage).可以被正确解包(通过Content-Lenght首部和Content-Encoding首部).是最新的(通过实体验证码和缓存过期控制).符合用户需要(基于Accept系列的内容协商首部).在网络上可以快速有效的传输(通过范围请求、差异编…

Http协议(5)—HTTP摘要认证

一、摘要认证的改进1.用摘要保护密码客户端不发送密码,而是发送一个摘要&#xff0c;服务端只需验证这个摘要是否和密码相匹配2.单向摘要a.摘要是一种单向函数,将无限的输入值转化为有限的b.常见的摘要为MD5&#xff1a;将任意长度的字节序列转换为一个128位的摘要;MD5的128位摘…

Http协议(4)—HTTP认证机制

一、认证1.HTTP质询/响应认证框架服务器收到一条请求并没有按照请求执行动作,而是以一个认证质询执行响应,要求用户提供一个保密信息说明他是谁,当用户再次发送请求时要附上保密证书,如果证书匹配则执行请求,否则返回一条错误信息2.认证协议与首部官方的两个认证协议:基本认证、…

Http协议(6)—安全HTTP

一、保护HTTP的安全1.功能:.服务器认证:客户端知道它是在与真正的服务器进行通信.客户端认证:服务器知道它是在与真正的客户端进行通信.完整性:服务器与客户端的数据不会被修改.加密:客户端与服务器的对话是私密的,不会被窃听.效率:运行足够快的算法.普适性:所有客户端和服务器…

Apache JMeter--网站自动测试与性能测评

Apache JMeter--网站自动测试与性能测评2013-02-28 15:48:05标签&#xff1a;JmeterFrom:http://bdql.iteye.com/blog/291987 出于学习热情&#xff0c;翻译总结Emily H. Halili的《Apache JMeter》一书的部分内容。 JMeter的简介 可以肯定的是&#xff0c;JMeter至少符合以下几…

hdu3081 Marriage Match II(最大流)

转载请注明出处&#xff1a; http://www.cnblogs.com/fraud/ ——by fraud Marriage Match II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2410 Accepted Submission(s): 820 Problem Descriptio…

log4net 日志框架的配置

log4net 日志框架的简单配置 添加对log4net程序集的引用 选择程序集文件添加引用即可&#xff0c;需要注意的是需要添加相应程序版本的程序集&#xff0c;如果你的应用是基于.netFramework2.0&#xff0c;则应选择net 2.0版本的程序集 修改配置文件&#xff0c;配置log4net相…

CSS 设计指南(第3版) 初读笔记

第1章 HTML标记与文档结构 关于<title>标签&#xff1a;搜索引擎会给<title>标签中的文字内容赋予很高的权重。而且这些文字也会作为网页标题出现在搜索结果列表中。 无论你想了解哪个HTML元素&#xff0c;第一个要问的问题都应该是&#xff1a;它是块元素&#xf…

Objective-C中的@property和@synthesize用法

代表“Objective-C”的标志&#xff0c;证明您正在使用Objective-C语言 Objective-C语言关键词&#xff0c;property与synthesize配对使用。 功能&#xff1a;让编译好器自动编写一个与数据成员同名的方法声明来省去读写方法的声明。 如&#xff1a; 1、在头文件中&#xff1a;…

Android用户界面程序设计示例

[例1]按钮和Toast弹出对话框 1 [例2] TextView文本框 &#xff08;1&#xff09; 3 [例3]TextView文本框 &#xff08;2&#xff09; 4 [例4]编辑框EditText 4 [例5]单选RadioButton 6 [例6]Toast的用法简介 8 [例7]多选checkbox 12 [例8]菜单Menu 14 …

Spring Thread Pool 线程池的应用

Spring and Java Thread example 扫扫关注“茶爸爸”微信公众号坚持最初的执着&#xff0c;从不曾有半点懈怠&#xff0c;为优秀而努力&#xff0c;为证明自己而活。Download it – Spring-Thread-Example.zip (22 KB)转自&#xff1a;http://www.mkyong.com/spring/spring-and…

Emule使用Upnp,解决Lowid和port not reachable的问题

路由器上钩选开启Upnp Emule->选择->扩展选项->Upnp&#xff0c; 服务器&#xff1a;【从URL更新】http://upd.emule-security.org/server.met转载于:https://www.cnblogs.com/zhyong/p/4422139.html

Android动画及滑动事件冲突解决(转载)

原文链接&#xff1a;http://blog.csdn.net/singwhatiwanna/article/details/38168103 Android开发中动画和事件处理是程序员迈向高手的必经之路&#xff0c;也是重点和难点。 此篇转载文章思路清晰&#xff0c;结构合理&#xff0c;用图文混合的方式完美的讲解了动画和事件冲突…

使用临时表解决union和order by不能同时使用的问题

最近遇见了这样一个问题&#xff0c;有4张表&#xff0c;A&#xff08;单据&#xff09;表&#xff0c;B&#xff08;产品&#xff09;表&#xff0c;C&#xff08;产品类型&#xff09;&#xff0c;D&#xff08;单据产品关联表&#xff09;。 B表有唯一对应的类型C&#xff…

2.3线性表的链式存储和运算—双向链表

以上讨论的单链表的结点中只有一个指向其后继结点的指针域next&#xff0c;因此若已知某结点的指针为p&#xff0c;其后继结点的指针则为p->next &#xff0c;而找其前驱则只能从该链表的头指针开始&#xff0c;顺着各结点的next 域进行&#xff0c;也就是说找后继的时间性能…

通过栈(Stack)实现对树的遍历

说到数的遍历树&#xff0c;长期以来的第一印象都是通过递归去实现。然而今天看了某位前辈的代码&#xff0c;才发现使用栈去实现遍历是那么简单。理论上通过数组也是可以实现同等功能的&#xff0c;毕竟Stack也是通过数据去实现的。 package com.sysway.ui.widget;import jav…