Luogu P3320尋寶遊戲(Splay)

2022-05-01 00:45:15 字數 2658 閱讀 3415

題目鏈結

其實這題用set就完事了但我不會set

智商-=inf

求虛樹上所有邊權和的兩倍。

具體方式就是splay把所有在虛樹上的點存一下,(按照dfs序排序的)每次插入/刪除會更新前驅和它、後繼和它、前驅和後繼的值

#include#include

#include

#include

#include

#include

#define maxn 200020

using

namespace

std;

inline

long

long

read()

while

(isdigit(ch))

return num*f;

}struct

splaytree[maxn];

introot,tot;

splay()

inline

int iden(int x)

inline

void connect(int x,int fa,int how)

inline

void update(int x)

void rotate(int

x)

void splay(int pos,int

to)

else}}

inline

int create(int fa,int

val),fa,val,1

};

return

tot;

}inline

int build(int

val)

int now=root;

while

(now)

now=tree[now].e[nxt];}}

inline

void insert(int

val)

inline

int find(int

val)

return0;

}void dele(int

x)

void pop(int

val)

int deal=tree[now].e[0

];

while(tree[deal].e[1]) deal=tree[deal].e[1

]; splay(deal,tree[now].e[

0]);

connect(tree[now].e[

1],deal,1

); root=deal; tree[deal].fa=0

; update(deal);

dele(now);

return

; }

inline

int lower(int

val)

return

ans;

}inline

int upper(int

val)

return

ans;

}}s;int d[maxn][21

];long

long w[maxn][21

];int

dfn[maxn],id;

intdeep[maxn];

bool

ext[maxn];

intback[maxn];

long

long

dis[maxn];

struct

edgeedge[maxn*2

];int

head[maxn],num;

inline

void add(int

from,int to,long

long

val);

head[

from]=num;

}void find(int x,int

fa)

return;}

long

long calcdis(int x,int y,int

opt)

if(x==y) return opt==0?ans:x;

for(int i=20;i>=0;--i)

return opt==0?ans+w[x][0]+w[y][0]:d[x][0];}

intmain()

find(

1,1);

for(int j=1;j<=20;++j)

for(int i=1;i<=n;++i)

long

long ans=0

;

while(m--)

else

int last=s.lower(n+1),first=s.upper(0

);

long

long ret=0

;

if(last>0&&first<=n)

printf(

"%lld\n

",ans+ret);

}return0;

}

LG3320 SDOI2015 尋寶遊戲

洛谷 不需要建虛樹的虛樹2333。貪心地想一下,起始節點肯定是在關鍵點上,訪問順序就是 dfs 序。那麼對於每次詢問,ans dis s 1,s s sum dis s i,s 用 set 維護一下就好了 include include include include include include...

P3320 SDOI2015 尋寶遊戲

我們考慮現在已知點集,如何求最後的答案。發現答案就是求所有點構成的最小生成樹的邊權和減去最小生成樹直徑。嗯 這個東西我好像不會動態維護啊。哦,發現要回到最初轉移到的村莊,那不就是兩倍的最小生成樹的邊權嗎,題目變簡單了一點。現在就是考慮動態維護最小生成樹的邊權和,我們考慮將邊權下放。那麼當前這棵樹的答...

P3320 SDOI2015 尋寶遊戲 題解

題面 需要動態維護乙個點集的極小聯通子圖邊權和。可以發現,將點集 中的點按照 dfs 序從小到大排序之後,dist a 1,a 2 dist a 2,a 3 ldots dist a a k dist a k,a 1 恰好等於我們要維護的那個邊權和的兩倍。所以就開乙個set,在加入和刪除的時候加上或...