LG3320 SDOI2015 尋寶遊戲

2022-05-07 20:12:09 字數 1381 閱讀 6405

洛谷

不需要建虛樹的虛樹2333。。。

貪心地想一下,起始節點肯定是在關鍵點上,訪問順序就是\(dfs\)序。

那麼對於每次詢問,

\[ans=dis(s_1,s_s)+\sum_^dis(s_i,s_)

\]用\(set\)維護一下就好了

**

#include #include #include #include #include #include #include using namespace std; 

inline int gi()

typedef long long ll;

const int max_n = 1e5 + 5;

struct graph e[max_n << 1];

int fir[max_n], e_cnt;

void cleargraph()

void add_edge(int u, int v, int w) ; fir[u] = e_cnt++; }

int n, m;

ll dis[max_n], ans;

int dep[max_n], size[max_n], top[max_n], son[max_n], fa[max_n], dfn[max_n], tim;

void dfs1(int x)

} void dfs2(int x, int tp)

} int lca(int u, int v)

return dep[u] < dep[v] ? u : v;

} ll dis(int x, int y)

struct cmp } ;

sets = set(cmp());

set:: iterator ite;

bool vis[max_n];

int main ()

dfs1(1), dfs2(1, 1);

while (m--)

int pre, nxt;

if (ite == s.begin()) pre = *--s.end();

else pre = *(--ite), ++ite;

if (ite == --s.end()) nxt = *s.begin();

else nxt = *(++ite), --ite;

ans -= dis(pre, x) + dis(x, nxt) - dis(pre, nxt);

p1 :

s.erase(ite);

} else

vis[x] ^= 1;

printf("%lld\n", ans);

} return 0;

}

Luogu 3320 SDOI2015 尋寶遊戲

一開始還真沒想到。發現從所有有寶藏的點出發繞一圈只要不刻意繞路答案都是一樣的,即我們呢要求的最後答案 ans dis x 1,x 2 dis x 2,x 3 dis x x k dis x k,x 1 不刻意繞遠路怎麼辦呢,我們把有寶藏的點按照 dfs 序,維護乙個有序的 set 就可以了。每次插入...

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,在加入和刪除的時候加上或...