SPOJ QTREE2 (LCA - Multiplier Online)

You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. Each edge has an integer value assigned to it, representing its length.

We will ask you to perfrom some instructions of the following form:

  • DIST a b : ask for the distance between node a and node b
    or
  • KTH a b k : ask for the k-th node on the path from node a to node b

Example:
N = 6 
1 2 1 // edge connects node 1 and node 2 has cost 1 
2 4 1 
2 5 2 
1 3 1 
3 6 2 

Path from node 4 to node 6 is 4 -> 2 -> 1 -> 3 -> 6 
DIST 4 6 : answer is 5 (1 + 1 + 1 + 2 = 5) 
KTH 4 6 4 : answer is 3 (the 4-th node on the path from node 4 to node 6 is 3) 

Input

The first line of input contains an integer t, the number of test cases (t <= 25). ttest cases follow.

For each test case:

  • In the first line there is an integer N (N <= 10000)
  • In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between ab of cost c (c <= 100000)
  • The next lines contain instructions "DIST a b" or "KTH a b k"
  • The end of each test case is signified by the string "DONE".

There is one blank line between successive tests.

Output

For each "DIST" or "KTH" operation, write one integer representing its result.

Print one blank line after each test.

Example

Input:
1

6
1 2 1
2 4 1
2 5 2
1 3 1
3 6 2
DIST 4 6
KTH 4 6 4
DONE

Output:
5
3 

ideas:
Multiply naked questions. . . Set of boards,
you need to deal with it when you ask for the kth one, and nothing else. , .
Implementation code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int M = 2e5+10;
int dist[M],p[M][30],dep[M],head[M];
int cnt1,n;

struct node{
    int to,next,w;
}e[M];

void add(int u,int v,int w){
    e[++cnt1].w=w;e[cnt1].to=v;e[cnt1].next=head[u];head[u]=cnt1;
    e[++cnt1].w=w;e[cnt1].to=u;e[cnt1].next=head[v];head[v]=cnt1;
}

void dfs(int u){
    for(int i = head[u];i != -1;i=e[i].next){
        int v = e[i].to;
        if(v == p[u][0]) continue;
        dep[v] = dep[u] + 1 ;
        dist[v] = dist[u] + e[i].w;
        p[v][ 0 ] = u; // p[i][0] stores i's parent node 
        dfs(v);
    }
}

void init(){
    for(int j = 1;(1<<j)<=n;j++){
        for(int i = 1;i <= n;i++){
            p[i][j] = p[p[i][j-1]][j-1];
            //cout<<i<<" "<<j<<" "<< p[i][j]<<endl;
        }
    }
}

int lca( int a, int b){
     if (dep[a] > dep[b]) swap(a,b);
     int h = dep[b] - dep[a]; // h is the height difference 
    for ( int i = 0 ;( 1 <<i)<=h;i++){   // (1<<i)&f find the position where h is converted to binary 1 and move to the corresponding position 
        if (( 1 << i)&h) b = p[b][i];
         // such as h = 5(101), first move 2^0 ancestors, then move 2^2 ancestors 
    }
     // cout<<a<<" "< <b<<endl; 
    if (a!= b){
         for ( int i = 22 ;i >= 0;i -- ){
             if (p[a][i]!=p[b][i]){   // Start from the largest ancestor, judge whether a and b ancestors are the same 
                a = p[a][i] ; b = p[b][i]; // If not the same, a,b, move up 2^j at the same time 
            }
        }
        a = p[a][ 0 ]; // The father of a is LCA 
    }
     return a;
}

int kth(int u,int k){
    for(int i = 0;i < 22;i ++)
        if(k >> i&1)
            u = p[u][i];
    return u;
}

intmain ()
{
    int t,u,v,w,k;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        cnt1 = 0;
        //init();
        memset(head,-1,sizeof(head));
        for(int i = 0;i < n-1;i ++){
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
        }
        dfs(1);
        init();
        char s[10];
        while(scanf("%s",s)!=EOF){
            if(s[1]=='O') break;
            scanf("%d%d",&u,&v);
            int num = lca(u,v);
            if(s[1]=='I'){
                printf("%d\n",dist[u]+dist[v]-2*dist[num]);
            }
            if(s[1]=='T'){
                scanf("%d",&k);
                int x = dep[u] - dep[num];
                if(x + 1 >= k)
                    printf("%d\n",kth(u,k-1));
                else printf("%d\n",kth(v,dep[v]+dep[u]-2*dep[num]+1-k));
            }
        }
    }
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324838055&siteId=291194637
lca