HDU 5266 pog loves szh III
来源:互联网 发布:网络射击游戏那个好玩 编辑:程序博客网 时间:2024/05/21 03:25
点击打开链接
一棵树一共有3*10^5个结点,标号为1~N,接下来有3*10^5个询问,给出两个数字L,R,问标号L到R的最近公共祖先是几号结点,默认1号结点为树根。
首先要注意一个问题,这里有10^5数量级的点,如果退化成一条链,在进行dfs的时候就会爆栈,解决方法有3,bfs或者手动dfs或者加黑科技
<span style="font-size:14px;">#pragma comment(linker, "/STACK:102400000,102400000")</span>
注:黑科技只能在C++编译器使用,G++没有这个优化
因为是连续的区间查询,比较容易想到的就是使用线段树来维护,当查询到两个子段时,只要在合并的时候求一下它们的公共祖先即可。每次查询的线段树操作是O(logn)的复杂度,而对于LCA则可以使用在线倍增法。这样查询的过程就是O(log^2n)。
O(n)建树,整个查询为O(Qlog^2n),复杂度为O(Qlog^2n)。大约为10^7~8。
#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;#define N 300010#define ls rt<<1#define rs rt<<1|1#define lson l,mid,ls#define rson mid+1,r,rs#pragma comment(linker, "/STACK:102400000,102400000")struct node{ int fa;}Tree[N<<2];vector<int>G[N];int dep[N],fa[N][20];void dfs(int u,int f,int d){ fa[u][0] = f; dep[u] = d; for(int i = 0;i<G[u].size();i++){ int v = G[u][i]; if(v!=f){ dfs(v,u,d+1); } }}int LCA(int a,int b){ int i,j; if(a == -1) return b; if(b == -1) return a; if(dep[a] < dep[b]) swap(a,b); for(i = 0;(1<<i) <= dep[a];i++); i--; for(j = i;j >= 0;j--) if(dep[a]-(1<<j)>=dep[b]) a = fa[a][j]; if(a == b) return a; for(j = i;j >= 0;j--){ if(fa[a][j]!=-1&&fa[a][j]!=fa[b][j]){ a = fa[a][j]; b = fa[b][j]; } } return fa[a][0];}void pushup(int rt){ Tree[rt].fa = LCA(Tree[ls].fa,Tree[rs].fa);}void build(int L,int R,int l,int r,int rt){ int mid; if(l == r){ Tree[rt].fa = l; return ; } mid = (l + r) >> 1; build(L,R,lson); build(L,R,rson); pushup(rt);}int query(int L,int R,int l,int r,int rt){ int mid; if(L <= l && r <= R){ return Tree[rt].fa; } mid = (l + r) >> 1; int a,b; a = b = -1; if(L <= mid) a = query(L,R,lson); if(R > mid) b = query(L,R,rson); int ret = LCA(a,b); return ret;}void init(int n){ memset(fa,-1,sizeof(fa)); for(int i = 0;i <= n+1;i++) G[i].clear();}void init2(int n){ int i,j; for(int j = 1;(1<<j)<= n;j++){ for(int i = 1;i <= n;i++){ if(fa[i][j-1]!=-1) fa[i][j] = fa[fa[i][j-1]][j-1]; } }}int main(){ int n,u,v,ans,q; while(~scanf("%d",&n)){ init(n); for(int i = 1;i < n;i++){ scanf("%d%d",&u,&v); G[u].push_back(v); G[v].push_back(u); } dfs(1,1,1); init2(n); build(1,n,1,n,1); scanf("%d",&q); for(int i = 0;i < q;i++){ scanf("%d%d",&u,&v); ans = query(u,v,1,n,1); cout<<ans<<endl; } } return 0;}
0 0
- HDU 5266 pog loves szh III
- hdu 5266 pog loves szh III(LCA)
- HDU 5266 pog loves szh III
- pog loves szh III HDU
- HDU 5266 pog loves szh III (线段树+LCA)
- hdu 5266 pog loves szh III LCA+RMQ
- HDU 5266 pog loves szh III (LAC)
- HDU 5266 pog loves szh III (线段树+在线LCA转RMQ)
- HDU 5266 pog loves szh III(在线倍增LCA+ST)
- HDU 5266 pog loves szh III 区间的LCA,ST表
- HDU 5264 pog loves szh I
- HDU 5265 pog loves szh II
- hdu 5265 pog loves szh II
- hdu 5264pog loves szh I
- hdu 5265 pog loves szh II
- hdu 5265 pog loves szh II
- hdu-5265pog loves szh II
- HDU ACM 5265 pog loves szh II
- 用map, next 和 reject 简化代码(ruby)
- Effective C++ 条款10
- C# 发送邮件源码
- IOS 三级联想菜单(也可以当二级)
- 深入浅出JSONP--解决ajax跨域问题
- HDU 5266 pog loves szh III
- VC处理键盘消息
- leetcode | Climbing Stairs
- 我看我自己系列——失去平静的原因
- sqlite constraint
- C#发送邮件代码
- 定时器Timer和定时任务TimerTask的用法
- ArcGIS 10.3.1正式发布
- 大三下学期期末对未来之路的思考