Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC optimize ("O3")
- #pragma GCC target ("sse4")
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- typedef long double ld;
- typedef complex<ld> cd;
- typedef pair<int, int> pi;
- typedef pair<ll,ll> pl;
- typedef pair<ld,ld> pd;
- typedef vector<int> vi;
- typedef vector<ld> vd;
- typedef vector<ll> vl;
- typedef vector<pi> vpi;
- typedef vector<pl> vpl;
- typedef vector<cd> vcd;
- #define FOR(i, a, b) for (int i=a; i<(b); i++)
- #define F0R(i, a) for (int i=0; i<(a); i++)
- #define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
- #define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
- #define sz(x) (int)(x).size()
- #define mp make_pair
- #define pb push_back
- #define f first
- #define s second
- #define lb lower_bound
- #define ub upper_bound
- #define all(x) x.begin(), x.end()
- #define ins insert
- mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- const int MOD = 1000000007;
- const char nl = '\n';
- const int MX = 100001; //check the limits, dummy
- const int L = 18;
- int anc[MX][L];
- int depth[MX];
- int parent[MX];
- int subsize[MX];
- vector<vi> graph(MX);
- int N;
- int lca(int a, int b) {
- if (depth[a] < depth[b]) {
- int c = b;
- b = a;
- a = c;
- }
- int dist = depth[a] - depth[b];
- while (dist > 0) {
- F0R(i, L) {
- if (dist & 1 << i) {
- a = anc[a][i];
- dist -= 1 << i;
- }
- }
- }
- if (a == b) return a;
- F0Rd(j, L) {
- if (anc[a][j] != -1 && anc[a][j] != anc[b][j]) {
- a = anc[a][j]; b = anc[b][j];
- }
- }
- return parent[a];
- }
- int lift(int v, int d) {
- F0R(i, L) {
- if (d & (1 << i)) {
- v = anc[v][i];
- }
- }
- return v;
- }
- int parDFS(int v, int p, int d) {
- parent[v] = p; depth[v] = d;
- int S = 1;
- F0R(i, sz(graph[v])) {
- int nxt = graph[v][i];
- if (nxt == p) continue;
- S += parDFS(nxt, v, d+1);
- }
- return subsize[v] = S;
- }
- void preprocess() {
- parDFS(0, -1, 0);
- F0R(i, N) F0R(j, L) anc[i][j] = -1;
- F0R(i, N) anc[i][0] = parent[i];
- FOR(j, 1, L) {
- F0R(i, N) {
- if (anc[i][j-1] != -1) {
- anc[i][j] = anc[anc[i][j-1]][j-1];
- }
- }
- }
- }
- int main() {
- ios_base::sync_with_stdio(0); cin.tie(0);
- cin >> N; int Q; cin >> Q;
- F0R(i, N-1) {
- int A, B; cin >> A >> B; A--; B--;
- graph[A].pb(B);
- graph[B].pb(A);
- }
- preprocess();
- while (Q--) {
- int A, B; cin >> A >> B; A--; B--;
- int ans = N-2;
- if (lca(A, B) == A) { // B is in the subtree of A
- ans -= N - subsize[lift(B, depth[B] - depth[A] - 1)] - 1;
- } else {
- ans -= subsize[A] - 1;
- }
- if (lca(A, B) == B) {
- ans -= N - subsize[lift(A, depth[A] - depth[B] - 1)] - 1;
- } else {
- ans -= subsize[B] - 1;
- }
- cout << ans << nl;
- }
- return 0;
- }
- // read the question correctly (ll vs int)
- // template by bqi343
Advertisement
Add Comment
Please, Sign In to add comment