这道题用 LCA 就可以水过去 , 但是我太弱了 QAQ 倍增写LCA总是写残...于是就写了树链剖分...

其实也不难写 , 线段树也不用用到 , 自己YY一下然后搞一搞就过了...速度还挺快的好像= = #9

----------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
 
#define rep( i , n ) for( int i = 0 ; i < n ; i++ )
#define clr( x , c ) memset( x , c , sizeof( x ) )
#define REP( x ) for( edge* e = head[ x ] ; e ; e = e -> next )
 
using namespace std;
 
const int maxn = 500000 + 5;
 
struct edge {
int to;
edge* next;
};
 
edge* pt , EDGE[ maxn << 1 ];
edge* head[ maxn ];
 
void edge_init() {
pt = EDGE;
clr( head , 0 );
}
 
void add( int u , int v ) {
pt -> to = v;
pt -> next = head[ u ];
head[ u ] = pt++;
}
#define add_edge( u , v ) add( u , v ) , add( v , u )
 
 
int fa[ maxn ] , top[ maxn ] , size[ maxn ] , son[ maxn ] , dep[ maxn ];
int id[ maxn ] , _id[ maxn ] , id_cnt = 0 , TOP;
 
void dfs( int x ) {
size[ x ] = 1;
son[ x ] = -1;
REP( x ) {
int to = e -> to;
if( to == fa[ x ] ) continue;
dep[ to ] = dep[ x ] + 1;
fa[ to ] = x;
dfs( to );
size[ x ] += size[ to ];
if( son[ x ] == - 1 || size[ to ] > size[ son[ x ] ] )
   son[ x ] = to;
}
}
 
void DFS( int x ) {
top[ x ] = TOP;
id[ x ] = ++id_cnt;
_id[ id_cnt ] = x;
if( son[ x ] != -1 )
   DFS( son[ x ] );
REP( x ) if( id[ e -> to ] < 0 )
   DFS( TOP = e -> to );
}
 
void DFS_init() {
clr( id , -1 );
dfs( dep[ 0 ] = 0 );
DFS( TOP = 0 );
}
 
int Q_LCA( int x , int y ) {
while( top[ x ] != top[ y ] ) {
if( dep[ top[ x ] ] < dep[ top[ y ] ] ) 
   swap( x , y );
x = fa[ top[ x ] ];
}
return dep[ x ] < dep[ y ] ? x : y;
}
 
int Q_dist( int x , int y ) {
int res = 0;
while( top[ x ] != top[ y ] ) {
if( dep[ top[ x ] ] < dep[ top[ y ] ] )
   swap( x , y );
res += id[ x ] - id[ top[ x ] ];
x = fa[ top[ x ] ];
res++;
}
if( dep[ x ] < dep[ y ] )
   swap( x , y );
return res + id[ x ] - id[ y ];
}
 
 
int ans[ 2 ];
void work( int x , int y , int z ) {
int LCA[ 3 ] = { Q_LCA( x , y ) , Q_LCA( x , z ) , Q_LCA( y , z ) };
if( LCA[ 0 ] == LCA[ 1 ] )
   ans[ 0 ] = LCA[ 2 ];
else if( LCA[ 0 ] == LCA[ 2 ] )
   ans[ 0 ] = LCA[ 1 ];
else 
   ans[ 0 ] = LCA[ 0 ];
ans[ 1 ] = Q_dist( x , ans[ 0 ] ) + Q_dist( y , ans[ 0 ] ) + Q_dist( z , ans[ 0 ] );
}
 
inline int read() {
int res = 0;
char c = getchar();
while( ! isdigit( c ) ) c = getchar();
while( isdigit( c ) ) {
res = res * 10 + c - '0';
c = getchar();
}
return res;
}
 
int main() {
freopen( "test.in" , "r" , stdin );
int n = read() , m = read();
edge_init();
rep( i , n - 1 ) {
int u = read() , v = read();
u-- , v--;
add_edge( u , v );
}
DFS_init();
while( m-- ) {
int x = read() , y = read() , z = read();
x-- , y-- , z--;
work( x , y , z );
printf( "%d %d\n" , ans[ 0 ] + 1 , ans[ 1 ] );
}
return 0;
}

----------------------------------------------------------------------------------

1787: [Ahoi2008]Meet 紧急集合

Time Limit: 20 Sec  Memory Limit: 162 MB
Submit: 1542  Solved: 683
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

6 4
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6

Sample Output

5 2
2 5
4 1
6 0

HINT

Source

BZOJ 1787: [Ahoi2008]Meet 紧急集合( 树链剖分 )的更多相关文章

  1. bzoj 1787: [Ahoi2008]Meet 紧急集合

    1787: [Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 ...

  2. bzoj 1787 [Ahoi2008]Meet 紧急集合(1832 [AHOI2008]聚会)

    1787: [Ahoi2008]Meet 紧急集合 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1841  Solved: 857[Submit][ ...

  3. BZOJ 1787: [Ahoi2008]Meet 紧急集合 LCA

    1787: [Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 ...

  4. BZOJ 1787: [Ahoi2008]Meet 紧急集合(lca+贪心)

    [Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 3 1 2 4 4 ...

  5. bzoj 1787: [Ahoi2008]Meet 紧急集合【树链剖分lca】

    对于三个点求最小路径长度和,答案肯定在某两个点的lca上,因为如果把集合点定在公共lca上,一定有两个点汇合后再一起上到lca,这样显然不如让剩下的那个点下来 这个lca可能是深度最深的--但是我懒得 ...

  6. BZOJ——1787: [Ahoi2008]Meet 紧急集合

    http://www.lydsy.com/JudgeOnline/problem.php?id=1787 题目描述 输入 输出 样例输入 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 ...

  7. 1787: [Ahoi2008]Meet 紧急集合

    1787: [Ahoi2008]Meet 紧急集合 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1482  Solved: 652[Submit][ ...

  8. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  9. [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...

随机推荐

  1. python 冒泡和快排,不多说【无聊】

    #-*-coding:utf8-*- import random a=[] b=[] def init_array(): for i in range(10000): v = random.randi ...

  2. PHP_Yii框架_专辑<一>

    一.PHP主流框架 cakephp—速度比较慢.CI(codeIgniter)—小型.symfony. TP(thinkphp)—国人开发.小型.zendframework(官方)—大型 Yii: 特 ...

  3. python自学笔记(九)python练习题

    1. 已知字符串 a = "aAsmr3idd4bgs7Dlsf9eAF",要求如下 1.1 请将a字符串的大写改为小写,小写改为大写 print a.swapcase() 1.2 ...

  4. synchronized和vilatile

    第一个程序 public class Test06 implements Runnable{ public int a = 0; public static void main(String[] ar ...

  5. mybatis+postgresql平台

    mybatis+postgresql平台        最近有个项目的数据库使用postgresql,使用原生态的mybatis操作数据,原生态的没什么不好,只不过国内有个tk.mybatis的工具帮 ...

  6. tomcat 会话超时设置

    1.为单个WEB设置SESSION 在WEB.XML中添加 xml 代码 <session-config> <session-timeout>15</session-ti ...

  7. 面试题:对一个正整数n,算得到1需要的最少操作次数

    实现一个函数,对一个正整数n,算得到1需要的最少操作次数.操作规则为:如果n为偶数,将其除以2:如果n为奇数,可以加1或减1:一直处理下去.例子:func(7) = 4,可以证明最少需要4次运算n = ...

  8. php 登录实例演示

    <pre name="code" class="python">一.模板的使用 (重点) a.规则 模板文件夹下[TPL]/[分组文件夹/][模板主 ...

  9. mfc删除标题和边框

    //删除标题和边框WS_CAPTION和WS_BORDER风格 ModifyStyle(WS_CAPTION, 0);ModifyStyle(WS_BORDER, 0);

  10. 提高IOS开发效率的常用网站、开源类库及工具

    时间过得很快,学习iOS也已经2年左右了.在这里整理一下,在平台平常开发过程中使用比较多的开源类库.网站与工具吧! 一.网站: UI网站: 1.https://www.cocoacontrols.co ...