HDU 5266 pog loves szh III 线段树,lca
Pog and Szh are playing games. Firstly Pog draw a tree on the paper. Here we define 1 as the root of the tree.Then Szh choose some nodes from the tree. He wants Pog helps to find the least common ancestor (LCA) of these node.The question is too difficult for Pog.So he decided to simplify the problems.The nodes picked are consecutive numbers from lili to riri ([li,ri])([li,ri]).
Input
Several groups of data (no more than 3 groups,n≥10000n≥10000 or Q≥10000Q≥10000).
The following line contains ans integers,n(2≤n≤300000)n(2≤n≤300000).
AT The following n−1n−1 line, two integers are bibi and cici at every line, it shows an edge connecting bibi and cici.
The following line contains ans integers,Q(Q≤300000)Q(Q≤300000).
AT The following QQ line contains two integers li and ri(1≤li≤ri≤n1≤li≤ri≤n).
Output
For each case,output QQ integers means the LCA of [li,ri][li,ri].
Sample Input
5
1 2
1 3
3 4
4 5
5
1 2
2 3
3 4
3 5
1 5
Sample Input
1
1
3
1
1
一颗树以1为根节点,给出区间范围,求范围内所有点的lca公共祖先,之前学的lca算法只能求两个点的,但考虑到是区间内进行操作,故考虑线段树。这道题如果了解线段树的话可以说没什么难度了...
做这道题这道题之前,没学过线段树...搞了好久才弄清楚,在网上抄了个线段树模板,弄清楚后没有想象中的难,实际上就是简单的lca+线段树组合罢了,可以说是模板题也不为过,收获就是学会了bfs树上倍增和搞清楚了线段树吧,
这个数据结构挺神奇的。
该题G++提交会TLE,C++提交如果不手动扩栈就会爆栈,当然也可以用BFS倍增就不用担心爆栈了。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <cstdio>
#include <queue>
#pragma warning ( disable : 4996 )
#pragma comment(linker, "/STACK:102400000,102400000") //防止爆栈 using namespace std; int Max( int x, int y ) { return x>y?x:y; }
int Min( int x, int y ) { return x>y?y:x; } const int inf = 0x3f3f3f3f;
const int vspot = 3e5 + ;
const int espot = 1e5 + ; struct node {
int from, to, next;
}e[vspot<<]; int N, Q, cnt, logn;
int lca[vspot<<], linjie[vspot];
int fa[vspot][], depth[vspot]; void addedge(int u, int v)
{
e[cnt].from = u; e[cnt].to = v;
e[cnt].next = linjie[u]; linjie[u] = cnt++;
e[cnt].from = v; e[cnt].to = u;
e[cnt].next = linjie[v]; linjie[v] = cnt++;
} void init()
{
cnt = ;
logn = ;
memset( linjie, -, sizeof(linjie) );
memset( lca, , sizeof(lca) );
memset( depth, , sizeof(depth) );
memset( fa, , sizeof(fa) );
} void dfs( int x )
{
for( int i = ; i <= logn; i++ )
if ( fa[x][i-] )
fa[x][i] = fa[fa[x][i-]][i-];
else
break;
for ( int i = linjie[x]; i+; i = e[i].next )
if ( fa[x][] != e[i].to )
{
fa[e[i].to][] = x;
depth[e[i].to] = depth[x]+;
dfs(e[i].to);
}
} void bfs( int x )
{
queue<int> Q;
Q.push(x); while (!Q.empty())
{
int run = Q.front();
Q.pop();
for( int i = linjie[run]; i+; i = e[i].next )
if ( fa[run][] != e[i].to )
{
fa[e[i].to][] = run;
depth[e[i].to] = depth[run] + ;
Q.push(e[i].to);
}
}
} void init2()
{
for ( int i = ; i <= logn; i++ )
for ( int x = ; x <= N; x++ )
fa[x][i+] = fa[fa[x][i]][i];
} int Lca( int u, int v )
{
if ( depth[u] < depth[v] )
swap(u,v);
int d = depth[u] - depth[v];
for ( int i = ; i <= logn; i++ )
if( (<<i)&d )
u = fa[u][i]; if ( u == v ) return u;
for ( int i = logn; i >= ; i-- )
if ( fa[u][i] != fa[v][i] )
{
u = fa[u][i];
v = fa[v][i];
}
return fa[u][];
} void pushUp( int pos ) { lca[pos] = Lca(lca[pos<<], lca[pos<<|]); } void build( int lhs, int rhs, int id )
{
if ( lhs == rhs )
{
lca[id] = lhs;
return;
}
int mid = ( lhs + rhs ) >> ;
build( lhs, mid, id<< );
build( mid+, rhs, id<<| ); pushUp(id);
} //lhs, rhs表示当前节点的区间,l,r表示要操作的区间
int query( int lhs, int rhs, int l, int r, int id )
{
if ( l <= lhs && r >= rhs )
return lca[id];
int mid = (lhs+rhs)>>; int llca = -, rlca = -;
if ( l <= mid ) llca = query( lhs, mid, l, r, id<< );
if ( r > mid ) rlca = query( mid+, rhs, l, r, id<<| ); if ( llca == - || rlca == - )
return Max(llca, rlca);
else
return Lca(llca, rlca);
} int main()
{
while ( ~scanf("%d", &N) )
{
init();
int x, y;
for( int i = ; i < N; i++ )
{ scanf("%d %d", &x, &y ); addedge(x,y); }
bfs();
init2();
// dfs(1); 用dfs并去掉上面两行也行
build(,N,); cin >> Q;
int ans;
for ( int i = ; i <= Q; i++ )
{
scanf( "%d %d", &x, &y );
ans = query( , N, x, y, );
printf( "%d\n", ans );
}
}
return ;
}
HDU 5266 pog loves szh III 线段树,lca的更多相关文章
- HDU 5266 pog loves szh III (线段树+在线LCA转RMQ)
题目地址:HDU 5266 这题用转RMQ求LCA的方法来做的很easy,仅仅须要找到l-r区间内的dfs序最大的和最小的就能够.那么用线段树或者RMQ维护一下区间最值就能够了.然后就是找dfs序最大 ...
- HDU 5266 pog loves szh III(区间LCA)
题目链接 pog loves szh III 题意就是 求一个区间所有点的$LCA$. 我们把$1$到$n$的$DFS$序全部求出来……然后设$i$的$DFS$序为$c[i]$,$pc[i]$为$c ...
- hdu 5266 pog loves szh III(lca + 线段树)
I - pog loves szh III Time Limit:6000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I ...
- HDU 5266 pog loves szh III ( LCA + SegTree||RMQ )
pog loves szh III Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Oth ...
- HDU 5266 pog loves szh III
题意:给出一棵树,1为根节点,求一段区间内所有点的最近公共祖先. 解法:用一棵线段树维护区间LCA.LCA是dp做法.dp[i][j]表示点i的第2^j个祖先是谁,转移方程为dp[i][j] = dp ...
- HDU 5266 pog loves szh III (LCA)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5266 题目就是让你求LCA,模版题.注意dfs会栈溢出,所以要扩栈,或者用bfs写. #pragma ...
- hdu 5265 pog loves szh II
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5265 pog loves szh II Description Pog and Szh are pla ...
- hdu 5264 pog loves szh I
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5264 pog loves szh I Description Pog has lots of stri ...
- hdu 5264 pog loves szh I 水题
pog loves szh I Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...
随机推荐
- windows系统下jupyter notebook使用虚拟环境
目录 [亲测好使]windows系统下jupyter notebook使用虚拟环境 在虚拟环境中安装jupyter,并添加到jupyter kernel 参考 [未测试,但觉得比上面那方法好,因为上面 ...
- java_Properties集合
package propertiesTest; import java.io.FileReader; import java.io.FileWriter; import java.io.IOExcep ...
- SpringCloud学习笔记《---04 Hystrix---》基础篇
- JS规则 给变量取个名字(变量命名) 必须以字母、下划线或美元符号开头;区分大小写;不允许使用JS关键字或保留字
给变量取个名字(变量命名) 我们为了区分盒子,可以用BOX1,BOX2等名称代表不同盒子,BOX1就是盒子的名字(也就是变量的名字). 我们赶快给变量取个好名字吧!变量名字可以任意取,只不过取名字要遵 ...
- ArrayBlockingQueue 和LinkedBlockQueue
ArrayBlockingQueue ArrayBlockingQueue是Java多线程常用的线程安全的一个集合,基于数组实现,继承自AbstractQueue,实现了BlockingQueue和S ...
- 如何在屏幕上查看命令的输出以及在Linux中写入文件
在Linux中输出命令可以做很多事情(http://www.nanke0834.com) 您可以将命令的输出分配给变量,将其发送到另一个命令/程序以通过管道进行处理或将其重定向到文件以进行进一步分析. ...
- windows安装apache系统中无apache2服务解决方案
一直都是用WIN开发PHP,今天有用户反映SHUGUANG CMS在APACHE+PHP中不能正常运行,只好自己机器配置个环境测试(http://xz.8682222.com)遇到点小问题,搜索相关资 ...
- 廖雪峰Java11多线程编程-3高级concurrent包-9Fork_Join
线程池可以高效执行大量小任务: Fork/Join线程池可以执行一种特殊的任务: 把一个大任务拆成多个小任务并行执行 Fork/Join是在JDK 1.7引入的 示例:计算一个大数组的和 Fork/J ...
- 0906NOIP模拟测试赛后总结
我进前十辣.然而有10个大佬去学LCT了于是没有考试. Dybala神和exzkt神分-rank1,奶风神和林哥分-rank3,wc.miemeng和DuanYue神140分-rank5. 我.ooo ...
- SpringData_02_JPQL查询、SQL查询和方法命名规则查询
1.使用JPQL的方式查询 JPQL查询:Hibernate提供的是HQL查询,而JPA提供的是JPQL查询语言 使用Spring Data JPA提供的查询方法已经可以解决大部分的应用场景,但是对于 ...