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.pswp.cn/news/273389.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/273389.shtml
英文地址,請注明出處:http://en.pswp.cn/news/273389.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux 數據轉換

使用bc 可以進行不同進制之間的轉換 digit100; printf "the number is : %d\n" $digit;binary$( echo "obase2;$digit" | bc );printf "result is : %s\n" $binary;digit1$( echo "obase10;ibase2;$binary" | bc );printf "bina…

PHP常用的正則表達式(有些需要調整)

平時做網站經常要用正則表達式&#xff0c;下面是一些講解和例子&#xff0c;僅供大家參考和修改使用&#xff1a; "^\d$"  //非負整數&#xff08;正整數 0&#xff09; 順平注: 驗證輸入id數值&#xff0c;不能為0 $reg1/^[1-9]\d*$/; "^[0-9]*[1-9][0-9]…

浮點數據的運算

使用bc設置scale可以進行相應的浮點運算#!/bin/bash# FileName TestBc.shdigit100;sqrt$(echo "scale3;sqrt($digit) " | bc);echo $sqrt;var$(echo "scale3;10/3" | bc);echo $var;var1$( echo "scale2;0.5*3" | bc);echo $var1;

IE(IE6/IE7/IE8)支持HTML5標簽--20150216

讓IE&#xff08;ie6/ie7/ie8&#xff09;支持HTML5元素&#xff0c;我們需要在HTML頭部添加以下JavaScript&#xff0c;這是一個簡單的document.createElement聲明&#xff0c;利用條件注釋針對IE來調用這個js文件。Opera&#xff0c;FireFox等其他非IE瀏覽器就會忽視這段代碼…

linux shell 求絕對值

abs-1;printf "the number is : %d\n" $abs;printf "abs is : %d\n" $abs;if [ $abs -lt 0 ]; thenlet abs0-$abs;fiprintf "abs is : %d\n" $abs;

PyQt中從RAM新建QIcon對象 / Create a QIcon from binary data

一般&#xff0c;QIcon是通過png或ico等圖標文件來初始化的&#xff0c;但是如果圖標資源已經在內存里了&#xff0c;或者一個zip壓縮文件內&#xff0c;可以通過QPixmap作為橋梁&#xff0c;轉換為圖標。 zf zipfile.ZipFile("library.zip") # 準備zip文件 pm …

Java中的代碼塊標記

taga: {for (int k 0; k < 5; k) {System.out.println("kkkkkk: " k);if (k > 3) {break taga;}tagb: for (int i 0; i < 10; i) {System.out.println("i: " i);if (i 2) {break tagb;}}}}

windows中安裝zookeeper

Zookeeper 分布式服務框架是 Apache Hadoop 的一個子項目&#xff0c;它主要是用來解決分布式應用中經常遇到的一些數據管理問題&#xff0c;如&#xff1a;統一命名服務、狀態同步服務、集群管理、分布式應用配置項的管理等。本文將從使用者角度詳細介紹 Zookeeper 的安裝和配…

MySQL Event

一、前言自MySQL5.1.6起&#xff0c;增加了一個非常有特色的功能–事件調度器(Event Scheduler)&#xff0c;可以用做定時執行某些特定任務&#xff08;例如&#xff1a;刪除記錄、對數據進行匯總等等&#xff09;&#xff0c;來取代原先只能由操作系統的計劃任務來執行的工作。…

Java中實現統計一個字符串在另一個字符串中出現的次數統計

public int getSubNum(String a,String b){int num0;String stra;int indexa.indexOf(b);while(index!-1){num;strstr.substring(indexb.length()-1);indexstr.indexOf(b);}return num;}

【編程練習】正整數分解為幾個連續自然數之和

題目&#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

c# 兩個數的加減乘除

Console.Title "加減乘除"; double x, y,z0; string m; int n0; Console.WriteLine("第一個數&#xff1a;"); x Convert.ToDouble(Console.ReadLine()); Console.WriteLine("運算符(默認為加)&#xff1a;"); m Console.ReadLine(); m (m &…

mysql建表語句

在sql語句中注意“約束的概念": 1.實體完整性約束(主鍵--唯一且非空) primary key()違約處理:No action(拒絕執行)2.參照完整性約束(外鍵約束)foregin key() references tableName(filedName) [on delete|update casecade | no action]違約處理:級聯更新或拒絕執行3.用戶自…

HTTP協議(1)—HTTP的連接

一、TCP連接過程:a.瀏覽器解析出主機名b.瀏覽器查詢出這個主機名的IP地址c.瀏覽器獲得端口號d.瀏覽器發起到ip:port的連接(TCP連接)e.瀏覽器向服務器發送一條HTTP報文f.瀏覽器從服務器讀取HTTP響應報文g.瀏覽器關閉連接1.TCP的可靠數據管道從TCP連接一端填入的字節會從另一端以…

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系列的內容協商首部).在網絡上可以快速有效的傳輸(通過范圍請求、差異編…

架構之美—軟件架構6大步驟(開篇)

1> 需求分析2> 領域建模3> 確定關鍵需求4> 概念架構設計5> 細化架構設計6 架構驗證 轉載于:https://www.cnblogs.com/kool/p/6695766.html

Http協議(2)—客戶端的識別與cookie機制

一、Http用戶識別的機制1.承載用戶身份的http首部2.客戶端IP地址跟蹤,根據客戶端IP地址進行識別3.用戶登錄,用認證方式識別用戶4.胖URL&#xff0c;一種在URL中嵌入識別信息的技術5.cookie,一種持久身份識別技術二、HTTP首部1.From包含用戶的Email地址2.User_Agent將用戶所用瀏…

經典PCB軟件比較闡述—Cadence和Mentor(整理)

PCB(Printed Circuit Board&#xff09;設計軟件經過多年的發展、不斷地修改和完善&#xff0c;或優存劣汰、或收購兼并、或強強聯合&#xff0c;現在只剩下Cadence和Mentor兩家公司獨大。 Cadence公司的推出的SPB(Silicon Package Board)系列&#xff0c;原理圖工具采…