Few people know, but a long time ago a developed state existed on Mars. It consisted of n cities, numbered by integers from 1 to n, the capital had the number 1. Some pairs of cities were connected by a road. The residents of the state were very prudent, therefore, between any two cities, there was exactly one path (possibly consisting of several roads).
Due to the fact that the state was developed, its residents loved traveling. Tourist route on Mars was described by two numbers L and R. This meant that the tourist started the route in the city L, then went to the city L + 1 (without going into the cities, that did not lie on the path between L and L + 1), then went to the city L + 2, and so on. The last city on the route was the city R. A city that was the closest to the capital among all cities visited on this route (if to count a distance between the cities by the roads) was considered the main attraction of the route.
Knowing the map of the Martian state and all the tourist routes, find for each route its main attraction.

Input

The first line contains an integer n that is the number of cities (1 ≤ n ≤ 2 · 105).
The following n − 1 lines describe the roads. Each road is described by two numbers of cities that are connected by it (1 ≤  v i,  u i ≤  nv i ≠  u i).
The ( n + 1)-th line contains an integer q that is the number of tourist routes (0 ≤ q ≤ 10 6).
Then q lines describe the routes themselves. Each route is described by a pair of integers L iR i (1 ≤ L i ≤ R i ≤ n).

Output

Output q integers, one per line — for each route the number of its main attraction. These numbers should be output in the same order in which the respective routes were described.

Example

input output
7
1 2
1 3
2 4
2 5
2 6
3 7
3
4 6
3 4
5 7
2
1
1
7
1 3
3 5
5 6
7 5
1 4
2 4
3
4 5
5 6
6 7
1
5
5

Notes

This problem has a big input and output data size and a strict Time Limit. If you write your solution in C++ we recommend you to use Visual C++ 2013 compiler.

题意就不描述了,是个水题,预处理出i和i+1的lca,然后询问的时候跑线段树就行,这里线段树用到了寻找区间中最小的点的位置,存一下。

懒得改非递归,要手动开栈。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 200010
int n,m;
int v[N<<1],__next[N<<1],first[N],e;
void AddEdge(int U,int V)
{
v[++e]=V;
__next[e]=first[U];
first[U]=e;
}
int fa[N],dep[N],top[N],son[N],siz[N],tot;
void dfs(int U)
{
siz[U]=1;
for(int i=first[U];i;i=__next[i])
if(v[i]!=fa[U])
{
fa[v[i]]=U;
dep[v[i]]=dep[U]+1;
dfs(v[i]);
siz[U]+=siz[v[i]];
if(siz[v[i]]>siz[son[U]])
son[U]=v[i];
}
}
void df2(int U)
{
if(son[U])
{
top[son[U]]=top[U];
df2(son[U]);
}
for(int i=first[U];i;i=__next[i])
if(v[i]!=fa[U]&&v[i]!=son[U])
{
top[v[i]]=v[i];
df2(v[i]);
}
}
int lca(int U,int V)
{
while(top[U]!=top[V])
{
if(dep[top[U]]<dep[top[V]])
swap(U,V);
U=fa[top[U]];
}
if(dep[U]>dep[V])
swap(U,V);
return U;
}
int minv[N<<2];
void update(int p,int v,int rt,int l,int r)
{
if(l==r)
{
minv[rt]=v;
return;
}
int m=(l+r>>1);
if(p<=m) update(p,v,rt<<1,l,m);
else update(p,v,rt<<1|1,m+1,r);
minv[rt]=min(minv[rt<<1],minv[rt<<1|1]);
}
int lcas[N];
int query(int ql,int qr,int rt,int l,int r)
{
if(ql<=l&&r<=qr) return minv[rt];
int m=(l+r>>1),res=2147483647;
if(ql<=m) res=min(res,query(ql,qr,rt<<1,l,m));
if(m<qr) res=min(res,query(ql,qr,rt<<1|1,m+1,r));
return res;
}
int Find2(int v,int rt,int l,int r)
{
if(l==r) return l;
int m=(l+r>>1);
if(minv[rt<<1]==v) return Find2(v,rt<<1,l,m);
else return Find2(v,rt<<1|1,m+1,r);
}
int Findp(int ql,int qr,int v,int rt,int l,int r)
{
if(ql<=l&&r<=qr)
{
if(minv[rt]==v)
return Find2(v,rt,l,r);
return -1;
}
int m=(l+r>>1);
if(ql<=m)
{
int tmp=Findp(ql,qr,v,rt<<1,l,m);
if(tmp!=-1) return tmp;
}
return Findp(ql,qr,v,rt<<1|1,m+1,r);
}
int main()
{
// freopen("j.in","r",stdin);
int x,y;
scanf("%d",&n);
for(int i=1;i<n;++i)
{
scanf("%d%d",&x,&y);
AddEdge(x,y);
AddEdge(y,x);
}
top[1]=1;
dfs(1);
df2(1);
for(int i=1;i<n;++i)
{
lcas[i]=lca(i,i+1);
update(i,dep[lcas[i]],1,1,n-1);
}
scanf("%d",&m);
for(int i=1;i<=m;++i)
{
scanf("%d%d",&x,&y);
if(x==y)
printf("%d\n",x);
else
printf("%d\n",lcas[Findp(x,y-1,query(x,y-1,1,1,n-1),1,1,n-1)]);
}
return 0;
}

【最近公共祖先】【线段树】URAL - 2109 - Tourism on Mars的更多相关文章

  1. 「10.19」最长不下降子序列(DP)·完全背包问题(spfa优化DP)·最近公共祖先(线段树+DFS序)

    我又被虐了... A. 最长不下降子序列 考场打的错解,成功调了两个半小时还是没A, 事实上和正解的思路很近了,只是没有想到直接将前$D$个及后$D$个直接提出来 确实当时思路有些紊乱,打的时候只是将 ...

  2. 51 nod 1681 公共祖先 (主席树+dfs序)

    1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另 ...

  3. jzoj4918. 【GDOI2017模拟12.9】最近公共祖先 (树链剖分+线段树)

    题面 题解 首先,点变黑的过程是不可逆的,黑化了就再也洗不白了 其次,对于\(v\)的祖先\(rt\),\(rt\)能用来更新答案当且仅当\(sz_{rt}>sz_{x}\),其中\(sz\)表 ...

  4. hiho #1062 : 最近公共祖先·一(树,最近祖先)

    #1062 : 最近公共祖先·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho最近发现了一个神奇的网站!虽然还不够像58同城那样神奇,但这个网站仍然让小Ho乐在 ...

  5. [LC]235题 二叉搜索树的最近公共祖先 (树)(递归)

    ①题目 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先 ...

  6. [51nod 1681]公共祖先(dfs序+线段树合并)

    [51nod 1681]公共祖先(dfs序+线段树合并) 题面 给出两棵n(n<=100000)个点的树,对于所有点对求它们在两棵树中公共的公共祖先数量之和. 如图,对于点对(2,4),它们在第 ...

  7. 线段树、最短路径、最小生成树、并查集、二分图匹配、最近公共祖先--C++模板

    线段树(区间修改,区间和): #include <cstdio> #include <iostream> #include <cstring> using name ...

  8. 马路 树链剖分/线段树/最近公共祖先(LCA)

    题目 [问题描述] 小迟生活的城市是⼀棵树(树指的是⼀个含有 \(n\) 个节点以及 \(n-1\) 条边的⽆向连通图),节点编号从 \(1\) 到 \(n\),每条边拥有⼀个权值 \(value\) ...

  9. 洛谷P3379 【模板】最近公共祖先(LCA)(树链剖分)

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

随机推荐

  1. webpack 3.8 使用 extract-text-webpack-plugin 3.0 抽取css失败:You may need an appropriate loader to handle this file type.

    webpack 3.8.1 使用 extract-text-webpack-plugin 3.0.2 抽取css时失败,报错: ERROR in ./src/static/style/localTim ...

  2. Hadoop 学习之MapReduce

    MapReduce充分利用了分而治之,主要就是将一个数据量比较大的作业拆分为多个小作业的框架,而用户需要做的就是决定拆成多少份,以及定义作业本身,用户所要做的操作少了又少,真是Very Good! 一 ...

  3. boost 文件操作

    void testFileSystem() { boost::filesystem::path path("/test/test1"); //初始化 boost::filesyst ...

  4. ng的ngModel用来处理表单操作

    https://segmentfault.com/a/1190000009126012

  5. bzoj5091 [Lydsy1711月赛]摘苹果 概率题

    [Lydsy1711月赛]摘苹果 Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 174  Solved: 135[Submit][Status][Dis ...

  6. LVM to increase and reduce 10G size for /data

    =======================increase10G for/data=============================(system env /dev/MongoData00 ...

  7. Java之戳中痛点 - (4)i++ 和 ++i 探究原理

    先看一个例子: package com.test; public class AutoIncrement { public static void main(String[] args) { int ...

  8. shell编程---变量赋值

    echo $filen | awk -F. '{print $3}'  怎么把上边这行脚本产生的字串赋给一个变量啊,实际上会产生一个数, 这个变量用来存这个数.格式应该是怎么写的? a=`echo $ ...

  9. 设计模式功能概述(Design Patterns)

    1.Abstract Factory:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 2.Adapter:将一个类的接口转换成客户希望的另一个接口.Adapter模式使得原本由于 ...

  10. 状压dp的题目列表 (一)

    状压dp的典型的例子就是其中某个数值较小. 但是某个数值较小也不一定是状压dp,需要另外区分的一种题目就是用暴力解决的题目,例如UVA818 紫书215 题目列表: ①校长的烦恼 UVA10817 紫 ...