門
點分樹不卡常就別想過了。。。
問樹中最遠黑點對距離
帶修改點分樹入門作
原圖先亂跑一次點分治,儲存點分治的每個root之間的父子關係,得到一顆點分樹。然後我們的原圖除了求dis就可以不管了
學習題解中不認識的大佬所說的套路:
點分治得到點分樹
每個點用s1,
s2
s_1,s_2
s1,s2
兩個資料結構維護,依次容斥
修改和查詢都是樹高(logn)×
\times
×資料結構修改查詢複雜度
初始化可以視為n次修改
此題用堆維護
①第一種堆:維護當前節點的每個點分樹子樹中的maxdis
②第二種堆:維護當前節點的所有子樹到其點分樹father的dis
我們需要求的是某個節點作為中間點,它的兩個點分樹子樹中的maxdis之和最大,也需要用乙個堆來維護
技巧
此題堆需要刪除堆中間部分的數,可以多儲存乙個trash堆用來儲存要刪的數,用堆的時候判一下是否兩堆頂相同,相同彈掉即可
#include
#define re register
using
namespace std;
const
int n=
1e5+
10,m=
2*n,inf=
1e9;
int n,m;
int a[n]
;int head[n]
,nex[m]
,to[m]
,tot;
inline
void
build
(int u,
int v)
//--
namespace cutree
}void
dfs2
(int u,
int p)
}inline
intlca
(int x,
int y)
return dep[x]
?x:y;
}inline
intdis
(int x,
int y)
}//---
#define ap n*2+1
priority_queue<
int>t[n<<1]
,trash[n<<1]
;inline
void
add(
int u,
int w)
inline
void
del(
int u,
int w)
}inline
inttop
(int u)
inline
intsecond
(int u)
//---
int size,root,maxx;
int sz[n]
,fa[n]
;bool vis[n]
;void
find
(int u,
int f)
tmp=
max(tmp,size-sz[u]);
if(tmp}void
solve
(int u,
int f)
}inline
void
init()
//----
int last[n]
,pre;
inline
void
q_add
(int u)
}inline
void
q_del
(int u)
}char s[10]
;int
main()
init()
;for
(int i=
1;i<=n;i++
)q_add
(i);
int g=n;
scanf
("%d"
,&m)
;while
(m--
)else
}}
最後當然是加火車頭過的啦 ZJOI2007 棋盤製作
題目描述 西洋棋是世界上最古老的博弈遊戲之一,和中國的圍棋 象棋以及日本的將棋同享盛名。據說西洋棋起源於易經的思想,棋盤是乙個8 8大小的黑白相間的方陣,對應八八六十四卦,黑白對應陰陽。而我們的主人公小q,正是西洋棋的狂熱愛好者。作為乙個頂尖高手,他已不滿足於普通的棋盤與規則,於是他跟他的好朋友小w...
zjoi2007棋盤分割
西洋棋是世界上最古老的博弈遊戲之一,和中國的圍棋 象棋以及日本的將棋同享盛名。據說西洋棋起源於易經的思想,棋盤是乙個8 8大小的黑白相間的方陣,對應八八六十四卦,黑白對應陰陽。而我們的主人公小q,正是西洋棋的狂熱愛好者。作為乙個頂尖高手,他已不滿足於普通的棋盤與規則,於是他跟他的好朋友小w決定將棋盤...
ZJOI2007 報表統計
不想描述了,心累。兩個操作分別用splay和線段樹來維護 全域性的差值最小直接用splay在插入的時候維護前驅後繼即可 相鄰最小差值我們可以這樣搞 首先 用線段樹維護相鄰的最小值 可以注意到插入元素的操作,如果是在乙個元素之後反覆插入,這些元素之間更新出來的最小值是不會發生改變的。只有元素與元素之間...