思路:
诡异的树上倍增求LCA + 树上差分。。。 LCA模板敲错了,导致我改了好久好久。。。才改对
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<vector> #include<cstdlib> #include<algorithm> using namespace std; const int maxn = 100010; inline void qread(int &x){ x = 0; register int ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' && ch <= '9'){ x = 10 * x + ch - 48; ch = getchar(); } } int n, m; int deep[maxn]; int llog[maxn]; int f[maxn][25]; int val[maxn]; int g[maxn]; vector<int> G[maxn]; void dfs(int x){ for(int i=0; i<G[x].size(); ++i){ if(!deep[G[x][i]]){ f[G[x][i]][0] = x; deep[G[x][i]] = deep[x] + 1; dfs(G[x][i]); } } } int LCA(int x, int y){ if(deep[x] < deep[y]) swap(x, y); for(int k = llog[n]; k >= 0; k--){ if(deep[f[x][k]] >= deep[y]){ x = f[x][k]; } } if(x != y){ for(int k = llog[n]; k>=0; k--){ if(f[x][k]!= f[y][k]){ x = f[x][k]; y = f[y][k]; } } x = f[x][0]; } return x; } void dfs2(int x){ for(int i=0; i<G[x].size(); ++i){ if(G[x][i] != f[x][0]){ dfs2(G[x][i]); val[x] += val[G[x][i]]; } } } int main(void) { srand(25426); qread(n); qread(m); for(int i=2; i<=n; ++i) llog[i] = llog[i>>1] + 1; for(int i=1; i<n; ++i){ int x, y; qread(x); qread(y); G[x].push_back(y); G[y].push_back(x); } int rt = rand() % n + 1; deep[rt] = 1; dfs(rt); for(int j=1; j<=llog[n]; ++j) for(int i=1; i <= n; ++i) f[i][j] = f[f[i][j-1]][j-1]; for(int i=1; i<=m; ++i){ int x, y; qread(x), qread(y); int a = LCA(x, y); val[x]++; val[y]++; val[a]-=2; } dfs2(rt); int ans = 0; for(int i=1; i<=n; ++i){ if(i==rt) continue; if(val[i]==0){ ans+=m; }else if(val[i] == 1){ ans++; } } printf("%d\n", ans); }