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 思路:
倍增裸题。。。套板子,
求第k个的时候需要处理下,其他没什么。,。
实现代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int M = 2e5+;
int dist[M],p[M][],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 != -;i=e[i].next){
int v = e[i].to;
if(v == p[u][]) continue;
dep[v] = dep[u] + ;
dist[v] = dist[u] + e[i].w;
p[v][] = u; //p[i][0]存i的父节点
dfs(v);
}
} void init(){
for(int j = ;(<<j)<=n;j++){
for(int i = ;i <= n;i++){
p[i][j] = p[p[i][j-]][j-];
//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为高度差
for(int i = ;(<<i)<=h;i++){ //(1<<i)&f找到h化为2进制后1的位置,移动到相应的位置
if((<<i)&h) b = p[b][i];
//比如h = 5(101),先移动2^0祖先,然后再移动2^2祖先
}
//cout<<a<<" "<<b<<endl;
if(a!=b){
for(int i = ;i >= ;i --){
if(p[a][i]!=p[b][i]){ //从最大祖先开始,判断a,b祖先,是否相同
a = p[a][i]; b = p[b][i]; //如不相同,a,b,同时向上移动2^j
}
}
a = p[a][]; //这时a的father就是LCA
}
return a;
} int kth(int u,int k){
for(int i = ;i < ;i ++)
if(k >> i&)
u = p[u][i];
return u;
} int main()
{
int t,u,v,w,k;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
cnt1 = ;
//init();
memset(head,-,sizeof(head));
for(int i = ;i < n-;i ++){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
dfs();
init();
char s[];
while(scanf("%s",s)!=EOF){
if(s[]=='O') break;
scanf("%d%d",&u,&v);
int num = lca(u,v);
if(s[]=='I'){
printf("%d\n",dist[u]+dist[v]-*dist[num]);
}
if(s[]=='T'){
scanf("%d",&k);
int x = dep[u] - dep[num];
if(x + >= k)
printf("%d\n",kth(u,k-));
else printf("%d\n",kth(v,dep[v]+dep[u]-*dep[num]+-k));
}
}
}
return ;
}

SPOJ QTREE2 (LCA - 倍增 在线)的更多相关文章

  1. LCA(倍增在线算法) codevs 2370 小机房的树

    codevs 2370 小机房的树 时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点, ...

  2. SPOJ DISQUERY LCA + 倍增

    裸题,如此之水- Code: #include<cstdio> #include<algorithm> using namespace std; const int maxn ...

  3. POJ - 1330 Nearest Common Ancestors(dfs+ST在线算法|LCA倍增法)

    1.输入树中的节点数N,输入树中的N-1条边.最后输入2个点,输出它们的最近公共祖先. 2.裸的最近公共祖先. 3. dfs+ST在线算法: /* LCA(POJ 1330) 在线算法 DFS+ST ...

  4. 【LCA倍增】POJ1330-Nearest Common Ancestors

    [知识点:离线算法&在线算法] 一个离线算法,在开始时就需要知道问题的所有输入数据,而且在解决一个问题后就要立即输出结果. 一个在线算法是指它可以以序列化的方式一个个的处理输入,也就是说在开始 ...

  5. 【codevs2370】小机房的树 LCA 倍增

    2370 小机房的树  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0 ...

  6. LCA倍增算法

    LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 ...

  7. 洛谷 3379 最近公共祖先(LCA 倍增)

    洛谷 3379 最近公共祖先(LCA 倍增) 题意分析 裸的板子题,但是注意这题n上限50w,我用的边表,所以要开到100w才能过,一开始re了两发,发现这个问题了. 代码总览 #include &l ...

  8. CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先)

    CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先) 题意分析 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天, ...

  9. POJ.1986 Distance Queries ( LCA 倍增 )

    POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...

随机推荐

  1. centos 7 163 yum 源 python 2.7.5

    安装 repo 源. repo 源一般包括 base, updates, Extras 三部分. $ cd /etc/yum.repos.d/ $ wget http://mirrors.163.co ...

  2. PI monitor error process-RESOURCE_NOT_FOUND-转

    事务:sxi_monitor 状态:system error 类型:Request Message Mapping 错误简要:RESOURCE_NOT_FOUND 错误详细信息: <?xml v ...

  3. c# 解析百度图片搜索结果json中objURL图片原始地址

    // http://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&fp=result& ...

  4. 2017-2018-2 20155315《网络对抗技术》Exp7 :网络欺诈防范

    实验目的 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法. 实验内容 简单应用SET工具建立冒名网站 ettercap DNS spoof 结合应用两种技术,用DNS sp ...

  5. WPF 初学VisifireChart

    visifire今天登陆他们官网的时候,发现好像是挂掉了,不知道是不再运营了,还是单纯服务器出了问题. VisifireChart的效果不炫,但是对于一些项目,感觉够用的,所以,今天大概看了几篇博客, ...

  6. LoRa---数据包结构、跳频

    数据包结构  跳频扩频技术FHSS 人太懒,直接贴图,自己看!

  7. 微信小程序之页面传值(路由、页面栈、globalData、缓存)

    1. 通过url带参数传递 1.1 固定参数传递 例如,从 list 页面到 detail 页面, 传递一个或多个固定值 list页面传值: <!--pages/list/list.js--&g ...

  8. 移动端H5页面上传图片或多张图片

    传统PC网页上传文件,大家都已经熟悉,这里不做介绍. 本文简单介绍移动端常用上传图片功能.灵活使用轮询或长连接可实现PC与移动端数据同步,即PC端需要上传的图片是移动拍照下来或移动端硬盘储存的,不需要 ...

  9. 【ORACLE】碎片整理

    alter table test enable row movement; alter table test shrink space; execute dbms_stats.gather_table ...

  10. 使用plumbing命令来深入理解git add和git commit的工作原理

    前言: plumbing命令 和 porcelain命令 git中的命令分为plumbing命令和porcelain命令: porcelain命令就是我们常用的git add,git commit等命 ...