QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#518733 | #3847. Airline | wisniewskij | RE | 0ms | 0kb | C++20 | 3.6kb | 2024-08-14 03:39:22 | 2024-08-14 03:39:22 |
answer
#include <bits/stdc++.h>
#define ndl '\n'
#define ll unsigned long long
#define all(x) (x).begin(), (x).end()
using namespace std;
void dfs_sub_tree_size(ll v, const vector<vector<ll>> &G, vector<ll> &sub_tree_size, vector<ll> &parent) {
sub_tree_size[v] = 1;
for(auto x: G[v]) {
if(x != parent[v]) {
parent[x] = v;
dfs_sub_tree_size(x, G, sub_tree_size, parent);
sub_tree_size[v] += sub_tree_size[x];
}
}
}
void fill_depth_and_jump_table(vector<ll> &depth, vector<vector<ll>> &jump_table, const vector<ll> &parent) {
for(ll j=0; j<jump_table[0].size(); j++) {
for(ll i=2; i<jump_table.size(); i++) {
jump_table[i][j] = (j == 0) ? parent[i] : jump_table[jump_table[i][j-1]][j-1];
depth[i] = depth[jump_table[i][0]] + 1;
}
}
}
ll find_lca(ll x, ll y, const vector<ll> &depth, const vector<vector<ll>> &jump_table) {
if(depth[x] < depth[y]) swap(x, y);
ll depth_difference = depth[x] - depth[y];
for(ll i=0; (1<<i) <= depth_difference; i++)
if((1<<i)&depth_difference) x = jump_table[x][i];
if(x == y) return x;
for(ll i=jump_table[0].size()-1; i>=0; i--) {
while(jump_table[x][i] != jump_table[y][i]) {
x = jump_table[x][i];
y = jump_table[y][i];
}
}
return jump_table[x][0];
}
void fill_path(ll x, ll y, ll lca, const vector<ll> &depth, const vector<vector<ll>> &jump_table, vector<ll> &path) {
if(depth[x] < depth[y]) swap(x, y);
while (x != lca) {
path.push_back(x);
x = jump_table[x][0];
}
path.push_back(lca);
if(lca != y) {
vector<ll> stack;
while (y != lca) {
stack.push_back(y);
y = jump_table[y][0];
}
for(ll i=stack.size()-1; i>=0; i--)
path.push_back(stack[i]);
}
}
void fill_appendices(const ll lca, const vector<vector<ll>> &G, const vector<ll> &path, const vector<ll> &subtree_sizes, const vector<vector<ll>> &jump_table, vector<ll> &appendices) {
for(ll i=0; i<path.size(); i++) {
ll v = path[i], lower = (i != 0 ? path[i-1] : -1), upper = (i != path.size()-1 ? path[i+1] : -1);
appendices.push_back(1);
if(v == lca) {
appendices.back() += subtree_sizes[1] - subtree_sizes[lca];
}
for(auto x:G[v]) {
if(x != lower && x != upper && x != jump_table[v][0])
appendices.back() += subtree_sizes[x];
}
}
}
int main(){
ios_base::sync_with_stdio(0); cin.tie(0);
ll n, q; cin>>n>>q;
vector<vector<ll>> G(n+1);
for(ll i=0;i<n-1;i++) {
ll a, b; cin>>a>>b;
G[a].push_back(b);
G[b].push_back(a);
}
vector<ll> parent(n+1), sub_tree_size(n+1);
dfs_sub_tree_size(1, G, sub_tree_size, parent);
vector<ll> depth(n+1);
vector<vector<ll>> jump_table(n+1, vector<ll>(log(n)+1));
fill_depth_and_jump_table(depth, jump_table, parent);
while(q--) {
ll a, b; cin>>a>>b;
ll lca = find_lca(a, b, depth, jump_table);
vector<ll> path, appendices;
fill_path(a, b, lca, depth, jump_table, path);
fill_appendices(lca, G, path, sub_tree_size, jump_table, appendices);
ll ans = 0, left_sum = 0, half_cycle_length = ((path.size()-1)/2);
for(ll i=0; i<half_cycle_length; i++) {
left_sum += appendices[i];
ans += left_sum * appendices[appendices.size()-half_cycle_length+i];
}
cout<<ans<<'\n';
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
1000 100000 552 9 456 720 540 790 628 695 848 478 66 268 798 360 773 277 116 471 874 792 912 784 502 831 359 965 925 434 677 629 271 670 76 755 92 200 814 422 922 266 617 44 480 331 18 662 153 753 669 491 368 187 99 867 476 808 774 509 98 147 724 478 447 182 923 469 881 665 674 589 770 613 436 310 8...