#include <bits/stdc++.h>
#define I using
#define AK namespace
#define IOI std;
#define int long long
#undef INT_MIN
#define INT_MIN (LONG_LONG_MIN + 1145)
#undef INT_MAX
#define INT_MAX (LONG_LONG_MAX - 1145)
#define P1 "标记点1"
#define P2 "标记点2"
#define P3 "标记点3"
#define P4 "标记点4"
#define P5 "标记点5"
#define P6 "标记点6"
#define P7 "标记点7"
#define P8 "标记点8"
#define P9 "标记点9"
#define P0 "标记点0"
I AK IOI;
namespace CSP {
inline void read ( int &x ) {
x = 0;
char c = getchar();
int pn = 1;
while ( !isdigit ( c ) ) {
if ( c == '-' ) {
pn = -1;
}
c = getchar();
}
while ( isdigit ( c ) ) {
x = x * 10 + c - 48;
c = getchar();
}
x *= pn;
return;
}
inline void write ( int x ) {
if ( x < 0 ) {
putchar ( '-' ), x = -x;
}
if ( x >= 10 ) {
write ( x / 10 );
}
putchar ( x % 10 + 48 );
return;
}
struct inputstream {
inputstream operator>> ( int &x ) {
read ( x );
return *this;
}
} in;
struct outputstream {
outputstream operator<< ( int x ) {
write ( x );
putchar ( 10 );
return *this;
}
} out;
}
I AK CSP;
int N, Q;
int w[100007];
vector<int> e[100007];
int st_sum[20][100007]; // 代表从st_plc[i][j]向前,不包括j的区间权值和
int st_plc[20][100007]; // 代表j的2^i父节点
int d[100007]; // 这个节点的深度(以1为根)
bool vis[100007]; // dfs会用到
inline void dfs ( int u, int dep ) {
d[u] = dep;
// cout << "d[" << u << "] equals " << d[u];
for ( int v : e[u] ) {
if ( !vis[v] ) {
vis[v] = 1;
dfs ( v, dep + 1 );
// vis[v] = 0;
} else {
st_plc[0][u] = v;
st_sum[0][u] = w[v];
}
}
}
inline void build ( void ) {
vis[1] = 1;
dfs ( 1, 0 );
for ( int i = 1, k = 2; k <= N; i++, k <<= 1 ) {
for ( int j = 1; j <= N; j++ ) {
st_plc[i][j] = st_plc[i - 1][st_plc[i - 1][j]];
st_sum[i][j] = st_sum[i - 1][j] + st_sum[i - 1][st_plc[i - 1][j]];
}
}
return;
}
inline int query ( int u, int v ) {
int ans = w[u] + w[v];
if ( d[u] < d[v] ) {
swap ( u, v );
}
for ( int p = 19; p >= 0; p-- ) {
if ( d[st_plc[p][u]] >= d[v] ) {
ans += st_sum[p][u];
u = st_plc[p][u];
// out << d[u];
}
}
if ( u == v ) {
return ans - w[u];
}
for ( int p = 19; p >= 0; p-- ) {
if ( st_plc[p][u] != st_plc[p][v] ) {
ans += st_sum[p][u];
ans += st_sum[p][v];
u = st_plc[p][u], v = st_plc[p][v];
}
}
// out << u << v;
return ( ans + st_sum[0][u] );
}
signed main ( signed argc, char const *argv[] ) {
int u, v;
in >> N >> Q;
for ( int i = 1; i < N; i++ ) {
in >> u >> v;
e[u].push_back ( v );
e[v].push_back ( u );
}
for ( int i = 1; i <= N; i++ ) {
w[i] = e[i].size();
// out << d[i];
// out << w[i];
}
build();
while ( Q-- ) {
in >> u >> v;
out << query ( u, v );
}
return 0;
}
可能是有关ST表的问题,请大佬指教(╹▽╹)