JZOI 距離 Standard IO 題解

2022-02-13 08:21:11 字數 4587 閱讀 1451

洛谷ac通道

給出一棵樹,求樹上兩點間的距離

考慮用樹鏈剖分+線段樹做。將邊權下移,變成點的權值,然後統計點權和即可。

當然,注意,在統計點權時,實際上lca這個點的權值並不包含在我們的距離之內,因此需要減掉。

#include using

namespace

std;

#define n 10010inline

intread()

while

(isdigit(c))

return x *s;

}struct

node t[n

<< 1

];int

f[n];

int bian = 0

;inline

void add(int u, int v, int

w), f[u] =bian;

t[++bian] = (node), f[v] =bian;

return

;}

int dfn[n], cnt = 0

;int

fa[n], son[n], top[n], siz[n], deth[n];

inta[n];

intn, m;

/*---------樹鏈剖分start--------

*/#define v t[i].v

void dfs1(int now, int

father)

}return;}

void dfs2(int now, int

tp)

return;}

void dfs3(int now, int

father)

}return;}

#undef v

int lca(int x, int

y)

return deth[x] < deth[y] ?x : y;}/*

-----------end-------

*//*

---------線段樹start--------

*/struct

tree e[n

<< 2

];inline

void pushup(int

o)void build(int o, int l, int

r)

int mid = l + r >> 1

; build(o

<< 1

, l, mid);

build(o

<< 1 | 1, mid + 1

, r);

pushup(o);

return;}

int query(int o, int l, int r, int

in, int

end)

int mid = l + r >> 1

;

return query(o << 1, l, mid, in, end) + query(o << 1 | 1, mid + 1, r, in

, end);

}int ask_he(int x, int

y)

if(deth[x] >deth[y]) swap(x, y);

sum += query(1, 1

, n, dfn[x], dfn[y]);

return

sum;}/*

------------線段樹end------------

*/inline

void

clean();

memset(f,

0, sizeof

(f));

bian = 0

;

return; }

intmain()

dfs1(

1, 1

); dfs2(

1, 1

); dfs3(

1, 1

); build(

1, 1

, n);

while(m--)

puts(""

); }

return0;

}

但是啊,悄悄告訴你呀,這個方法,超慢噠! 好奇怪的語氣

根據zht大佬的思路,求出每個點到根的距離,然後每次詢問直接為 $dis_x + dis_y - 2 * dis_$

在此再次%%% + orz

樹剖版:

#include using

namespace

std;

#define n 10010inline

intread()

while

(isdigit(c))

return x *s;

}struct

node t[n

<< 1

];int

f[n];

int bian = 0

;inline

void add(int u, int v, int

w), f[u] =bian;

t[++bian] = (node), f[v] =bian;

return

;}

int dfn[n], cnt = 0

;int

fa[n], son[n], top[n], siz[n], deth[n];

inta[n];

intdis[n];

intn, m;

/*---------樹鏈剖分start--------

*/#define v t[i].v

void dfs1(int now, int

father)

}return;}

void dfs2(int now, int

tp)

return;}

int lca(int x, int

y)

return deth[x] < deth[y] ?x : y;

}inline

void

clean();

memset(f,

0, sizeof

(f));

bian = 0

;

return;}

intmain()

dfs1(

1, 1

); dfs2(

1, 1

);

while(m--)

puts(""

); }

}

倍增版:

#include using

namespace

std;

#define n 10010inline

intread()

while

(isdigit(c))

return x *s;

}struct

node t[n

<< 1

];int

f[n];

int bian = 0

;inline

void add(int u, int v, int

w), f[u] =bian;

t[++bian] = (node), f[v] =bian;

return

;}

int a[n][21

];int

fa[n], dis[n];

intdeth[n];

intn, m;

#define v t[i].v

void dfs(int now, int

father)

}return;}

#undef v

int lca(int x, int

y)

if(x == y) return

x;

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

return a[x][0];}

inline

void

clean();

memset(f,

0, sizeof

(f));

bian = 0

;

return;}

intmain()

dis[

1] = 0

; a[

1][0] = 1

; dfs(

1, 1

);

while(m--)

puts(""

); }

return0;

}

JZOI 4311 統一天下

洛谷ac通道!題目描述 從前有兩個國家 w 1 w 2 國家 w i i 有 n i 座城市,這 n i 座城市由 n i 1 條雙向道路相連。任意乙個國家的內部都是連通的。乙個國家的兩個點之間存在唯一的最短路,兩個點的距離是這條最短路上邊的數目。也可以理解為道路的長度均為 1 注意 w 1 和 w...

歐式距離 標準化歐式距離 馬氏距離 余弦距離

標準化歐氏距離 馬氏距離 夾角余弦距離 漢明距離 曼哈頓 manhattan 距離1,x2x1,x2 間的距離公式 ixi 的各個維度之間的尺度不一樣。對於尺度無關的解釋 如果向量中第一維元素的數量級是100,第二維的數量級是10,比如v1 100,10,30 v2 500,40 則計算歐式距離 2...

歐氏距離和余弦距離

一 歐幾里得距離 euclidean distance 歐氏距離是最常見的距離度量,衡量的是多維空間中各個點之間的絕對距離。公式如下 因為計算是基於各維度特徵的絕對數值,所以歐氏度量需要保證各維度指標在相同的刻度級別。eg 在深度學習中,提取cnns倒數的第二層fc作為最後的特徵向量,來進行人臉比對...