給定n個點,要維護三種操作:
find id u v t l:在u,v點間連一條編號id,溫度t,長度l的邊(保證溫度互不相同)。
move u v:詢問在u到v的路徑中,溫度從小到大排序後字典序最大的路徑的長度。若不存在路徑,輸出-1
change id l:將編號為id的邊長度改為l
sample input
8 19
find 0 0 2 7 2
find 1 2 4 4 4
find 2 4 6 10 1
find 3 6 7 8 6
move 2 7
move 1 6
find 4 2 5 3 4
move 0 5
change 0 12
find 5 4 5 5 10
find 6 2 3 6 9
move 3 5
find 7 0 1 12 1
move 1 6
find 8 1 7 11 100
move 1 6
move 3 7
move 5 6
move 2 2
sample out11-16
2318
106122
110
這個詢問的操作看起來很奇怪,但仔細分析一下,其實就是求整幅圖最大生成樹在u,v之間的鏈(不證明了)。只要維護好這棵最大生成樹就可以。
加入一條邊時,如果u,v本來就不在乙個聯通塊裡(並查集維護),直接連邊就可以。
如果在乙個聯通塊裡,這條新加的邊可能會替換原來的邊。如果新加的邊權還小於u,v間鏈上最小的邊權,就不用加邊了。否則把用新加的邊把最小邊權的邊替換掉。
而修改時,只改了長度,並沒有改最重要的溫度,所以沒什麼關係。
要加邊、刪邊,並維護書上一條鏈上的最小值,用lct維護就行了(其實不難寫)。
**:
#include
using
namespace
std;
int son[500010][2],tree[500010],a[500010],pos[500010],fa[500010],q[500010],rev[500010];
int fa[500010],u[500010],v[500010],n,m;
int sum[500010],l[500010];
char st[100];
inline
void swap(int &x,int &y)
inline
int find(int x)
inline
int isroot(int x)
inline
void pushdown(int u)
}inline
void update(int x)
void splay(int x)
rotate(x);
}}void access(int x)
}void makeroot(int u)
void split(int u,int v)
void link(int u,int v)
void cut(int u,int v)
void add(int u,int v,int val,int pos)
else
}}int main()
else
if (st[0]=='m')
else
puts("-1");
}else
if (st[0]=='c')
} return
0;}
bzoj 4736 溫暖會指引我們前行
題面lct維護最大生成樹即可 因為溫度互不相同 所以至少大的必須的邊都要走 又不可以多走 因為這題字典序的定義比較奇怪 多了反而不好 即lct上維護路徑和 維護邊的熱度最小 然後到時候替換即可 慶幸自己lct還能1a include include include include define fi...
清華集訓 溫暖會指引我們前行
emmm其實我在uoj上過不去,加的資料我tle了。但是bzoj上還是可以的。關於push up的小trick 初始化的時候給0節點也初始化成最大值,然後push up的時候不用管自己的左右兒子是否為空,直接返回左右兒子中比較小的乙個就可以了,然後再和自己作比較。qwqwq 如下 include i...
UOJ 274 溫暖會指引我們前行
傳送門 小r的宿舍樓中有 n nn 個地點和一些路,一條路連線了兩個地點,小r可以通過這條路從其中任意乙個地點到達另外乙個地點。但在剛開始,小r還不熟悉宿舍樓中的任何一條路,所以他會慢慢地發現這些路,他在發現一條路時還會知道這條路的溫度和長度。每條路的溫度都是互不相同的。小r需要在宿舍樓中活動,每次...