樹是任意兩點間僅有一條路徑的聯通圖,樹上的一條鏈定義為兩個點之間的路徑。在本題中定義一條鏈的長度為鏈上所有點的權值和。現有一棵帶點權樹,要對它進行一些操作,請你在第一次操作前和每一次操作後輸出這棵樹的最長鏈。
lct splay的時候判gf 是!isroot(f) 下次注意
這題非常不錯的虛邊維護兒子資訊的lct,並且,利用lct splay 維護的是鏈的性質,可以動態的利用最大子段和的方式進行合併,主要思想就是維護以x節點為根的子樹所表示的鏈的從頭開始的最大子段,從尾向前的最大子段(為了reverse),動態的合併其虛兒子的資訊求出答案.
套路:lct維護的是路徑資訊,序列上能做的,基本都能搬到lct上來做,剩下的路徑統計可以利用資料結構維護虛邊.
**:
%:pragma gcc optimize(4)
%:pragma gcc optimize("inline")
#include
using
namespace
std;
const
int n = 1e5 + 5;
int min(int x , int y)
int max(int x , int y)
#define lc ch[x][0]
#define rc ch[x][1]
struct node c , t[n];
multiset
cl[n] , cm[n];
multiset
::reverse_iterator it;
bool rev[n];
int n , m , x , y , rt , ch[n][2] , fa[n] , val[n] , u[n] , v[n];
inline node operator + (node a , node b)
inline
int get(int x)
inline
int get2(int x)
inline
void up(int x)
inline
void pt(int x)
inline
void pd(int x)
}inline
bool dir(int x)
#define isroot(x) (ch[fa[x]][1] != x && ch[fa[x]][0] != x)
inline
void dn(int x)
int dx , f , df , gf;
inline
void rotate(int x)
inline
void splay(int x)
if(dir(x) == dir(fa[x])) rotate(fa[x]) , rotate(x);
else rotate(x) , rotate(x);
}}#define del(k , p) k.erase(k.find(p))
inline
void a(int x , int y , int oh)
else
}inline
void access(int x)
}inline
void make_root(int x)
inline
void link(int x , int y)
inline
void cut(int x , int y)
inline
int getans(void)
char ty[23];
bool is;
void read(int &x)
while(isdigit(ch)) x = x * 10 + ch - '0' , ch = getchar();
if(is) x = -x;
}main(void)
else
printf("%d\n" , getans());
}}
leetcode演算法題 最長數對鏈
1 動態規劃 dp i 表示第i個位置最長的數對鏈的長度狀態轉移 dp i max dp j 1 j從0到i不過題目的數對是可以亂序的,所以我們先提前給按數對第乙個數來從小到大排序,然後再進行動態規劃。其實根據第二種貪心演算法,按第二個數來排序更好!static bool lessvector co...
某近似模板題2
p3388 模板 割點 割頂 題目背景 割點題目描述 給出乙個n個點,m條邊的無向圖,求圖的割點。輸入輸出格式 輸入格式 第一行輸入n,m 下面m行每行輸入x,y表示x到y有一條邊 輸出格式 第一行輸出割點個數 第二行按照節點編號從小到大輸出節點,用空格隔開 輸入輸出樣例 輸入樣例 1 複製 6 7...
FZU 2082 樹鏈剖分模板題
一顆樹邊上的權在變動,動態求兩點之間的和。include include include include include include include include include using namespace std define ll long long define pi acos 1....