這道題珂以用啟發式合併+主席樹來做
離線做法就不行了
我們就要用乙個叫做kruscal重構樹的東西來解決這個問題
克魯斯卡爾重構樹可以用來解決一類諸如「查詢從某個點出發經過邊權不超過val的邊所能到達的節點」的問題
首先不難發現,上面這個問題肯定是在最小生成樹上走最優,其他邊都可以不用去管
kruscal構樹的思想就是在建最小生成樹的時候不是直接連邊,而是新建乙個節點,並把這個節點的值設為邊權,然後令兩個連通塊的代表點分別作為它的左右兒子。然後令這個新節點成為整個連通塊的代表點
那麼這樣做有什麼用呢?
kruscal重構樹有這樣的性質:乙個點的所有子樹節點的權值都小於等於它的權值,並且從它開始逐漸向子節點移動,權值是單調不上公升的。這個性質是顯然的,因為我們在構造樹的時候是從小到大插入的邊,因此父親節點的權值一定大於等於子節點的值
查詢時,首先可以在樹上倍增得到當前查詢點所能夠到達的最遠的祖先點,那麼從這個點能夠到達的符合邊權限制條件的連通塊中的節點,就是祖先點的子樹中所有的葉節點
然後我們按dfs序維護乙個主席樹上樹就可以解決了
完整**(離線)
#include #define getchar nc
#define n 200005
#define m n<<4
#define k 500005
using namespace std;
inline char nc()
inline int read()
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}inline void write(register int x)
struct node
node(int u,int v,int c):u(u),v(v),c(c){}
inline bool operator <(const node &b)const
inline void update(register int last,register int &now,register int l,register int r,register int x)
inline int query(register int a,register int x,register int k)
return b[r];
}inline void dfs(register int u)
inline int find(register int x)
int main()
sort(e+1,e+m+1);
dfn=n;
for(register int i=1;i<=m;++i)
}for(register int i=1;i<=dfn;++i)
if(!ls[i])
dfs(find(i));
while(q--)
return 0;
}
#include #define getchar nc
#define n 200005
#define m n<<4
#define k 500005
using namespace std;
inline char nc()
inline int read()
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}inline void write(register int x)
struct node
node(int u,int v,int c):u(u),v(v),c(c){}
inline bool operator <(const node &b)const
inline void update(register int last,register int &now,register int l,register int r,register int x)
inline int query(register int a,register int x,register int k)
return b[r];
}inline void dfs(register int u)
inline int find(register int x)
int main()
sort(e+1,e+m+1);
dfn=n;
for(register int i=1;i<=m;++i)
}for(register int i=1;i<=dfn;++i)
if(!ls[i])
dfs(find(i));
int lastans=0,v,x,k;
while(q--)
return 0;
}
學習筆記 Kruscal 重構樹
網上感覺沒有什麼很詳細 證明的講解啊 前置 kruskal 求最小生成樹。這個演算法可以將一棵樹 無向連通圖重構成一顆有性質的新樹。演算法可以解決一些樹上瓶頸邊權之類的問題,可以把需要持久化的並查集給代替掉。設 f i 為 i 所在聯通塊的根。演算法流程和 kruskal 最小生成樹的過程非常類似 ...
基環樹略解
基環樹,也叫環套樹,是一種圖的型別。如果連通圖 g g g 有 v e v e v e 則我們稱它是基環樹。顧名思義,基環樹就好似是在一棵樹上加一條邊得到的圖。基環樹有且僅有乙個環,所以也被成為環套樹。如上圖所示的圖就是一棵基環樹。基環樹沒什麼用。它只能解決部分特殊問題,而這類問題通常會註明 邊數 ...
B樹 B 樹 B 樹 B 樹略解
b 樹 即二叉搜尋樹 1.所有非葉子結點至多擁有兩個兒子 left 和right 2.所有結點儲存乙個關鍵字 3.非葉子結點的左指標指向小於其關鍵字的子樹,右指標指向大於其關鍵字的子樹 如 b樹的搜尋,從根結點開始,如果查詢的關鍵字與結點的關鍵字相等,那麼就命中 否則,如果查詢關鍵字比結點關鍵字小,...