瞬移後無法區分兩者,分開時不妨稱下一次瞬移的為分身,即僅允許分身瞬移回本身
考慮本身,即從根節點出發向下移動的一條路徑,並稱路徑上分身曾瞬移到的點為關鍵節點(包括根節點)
對關鍵節點dp,定義$f_$表示當前兩者均在$k$且$k$子樹外所有點均被經過的最短時間
列舉上乙個關鍵節點,分析兩者的移動,不難得到轉移即
$$f_=\min_\big(f_+(g_-g_)-dep_(h_-h_)+\max(dep_-\max(d_,dep_),0)\big)
$$(其中$dep_$表示$k$的深度$,h_$表示$k$子樹中葉子個數$,g_$表示$k$子樹中葉子深度和$,d_$表示$x$子樹內除$k$子樹外最深的葉子)
另外,初始狀態即$f_=1$,最終答案即$\min f_+g_-dep_h_$
若$d_\ne 0$且$dep_>d_$,可以理解為其到達深度為$d_$的點後分身直接瞬移,顯然這樣不劣
同時,若$d_=0$,即$x$到$k$的這條鏈上(除$k$以外)沒有其他兒子,直接從$x=fa_$依次轉移即可
進一步的,若$x$不是第乙個滿足$dep_\le d_$的祖先,那麼不妨先轉移到該祖先再轉移到$k$,代入可得不劣
綜上,僅需考慮$x=fa_$(在$fa_$僅有$k$乙個兒子時)和第乙個滿足$dep_\le d_$的祖先
關於後者,對樹長鏈剖分,注意到其所在長鏈頂端的父親一定滿足
換言之,每一條長鏈內是獨立的,分別維護乙個單調棧執行上述過程即可
需要注意空間限制,由於保證編號,可以使用遍歷的方式代替dfs
時間複雜度為$o(n)$,可以通過
1 #include2view codeusing
namespace
std;
3#define n 5000005
4#define ll long long
5 vectorv[n];
6int
n,n0,st[n],vis[n],fa[n],dep[n],h[n],mx[n],cmx[n],son[n],top[n];
7ll ans,g[n],f[n];
8char s[n<<1];9
void get_val(int k,int x,int
mx)12
intmain()
22 st[++st[0]]=n0;23}
24for(int i=2;i<=n;i++)dep[i]=dep[fa[i]]+1;25
for(int i=n;i>1;i--)
32for(int i=1;i<=n;i++)
37 memset(f,0x3f,sizeof
(f));
38 f[1]=0;39
for(int i=1;i<=n;i++)
40if (!v[i].empty())
44 st[0]=0;45
for(int j=0;j)52}
53 ans=1e18;
54for(int i=1;i<=n;i++)ans=min(ans,f[i]+g[i]-(ll)dep[i]*h[i]);
55 printf("
%lld\n
",ans);
56return0;
57 }
字尾陣列水水水水水水題
首先 jxrjxrjxr orz,沒有您我們都會死 然後就是我從jxr神犇那裡借鑑 照抄 過來的字尾陣列模板。include include include define cmp x y sa i x y sa i 1 x using namespace std const int n 100000...
LeetCode刷題筆記 84
題目 柱狀圖中最大的矩形 給定 n 個非負整數,用來表示柱狀圖中各個柱子的高度。每個柱子彼此相鄰,且寬度為 1 求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。以上是柱狀圖的示例,其中每個柱子的寬度為 1,給定的高度為 2,1,5,6,2,3 圖中陰影部分為所能勾勒出的最大矩形面積,其面積為 10 個...
水題)簡單題
problem 2183 簡單題 現在有一些被簡單壓縮的字串,例如 a 120 代表120個a。對於字串acb 3 d 5 e相對於acbbbddddde 現在給你兩個字串cstring,nstring.乙個是被壓縮過的字串,另乙個沒有被壓縮。求nstring是否為cstring的子串,如果是輸出t...