(中等) Hiho 1232 Couple Trees(15年北京网络赛F题),主席树+树链剖分。
"Couple Trees" are two trees, a husband tree and a wife tree. They are named because they look like a couple leaning on each other. They share a same root, and their branches are intertwined. In China, many lovers go to the couple trees. Under the trees, lovers wish to be accompanied by a lifetime.
Ada and her boyfriend Asa came to the couple trees as well. They were very interested in the trees. They were all ACMers, so after careful observation, they found out that these two trees could be considered as two "trees" in graph theory. These two trees shared N vertices which were labeled 1 to N, and they all had exactly N vertices. Vertices 1 was the root of both trees.
Ada and Asa wanted to know more about the trees' rough bark, so each of them put one thumb at a vertices. Then they moved their thumbs towards the root. Ada moved along the wife tree, and Asa moved along the husband tree. Of course, they could moved at different speed.
At that moment, a thought suddenly came to Ada's mind: their thumbs may meet before the root. Which one was the earliest possible meeting vertex? And how many vertices would Ada and Asa encounter on the way to the meeting vertex?
题意差不多就是对于N个点有两棵树,也就是两棵树边不同但是共用所有点,然后询问两个点,问这两个点分别沿着两颗树向根部走,然后路径的交点中最近的那个。
相当经典的题目,比赛的时候就是没想出来,结果比赛完了一想到主席树这题就会了。。。
因为每个点都是向着根部走,所以这里应该自然而然想到主席树才对,因为每一个节点都是在其父亲的基础上加了一个点。
至于维护什么就想了一段时间了。。。
因为是两棵树,对第一颗树进行树链剖分,得到每个点剖分之后的位置,然后用主席树维护第二棵树的每个点,维护从根节点到这个点所经过的所有的点的树剖之后的位置。
然后询问的时候就让那个点在第一颗树上跑,每次询问一个区间,然后一直这样得到第一个位置就是了。。。
代码如下:
// ━━━━━━神兽出没━━━━━━
// ┏┓ ┏┓
// ┏┛┻━━━━━━━┛┻┓
// ┃ ┃
// ┃ ━ ┃
// ████━████ ┃
// ┃ ┃
// ┃ ┻ ┃
// ┃ ┃
// ┗━┓ ┏━┛
// ┃ ┃
// ┃ ┃
// ┃ ┗━━━┓
// ┃ ┣┓
// ┃ ┏┛
// ┗┓┓┏━━━━━┳┓┏┛
// ┃┫┫ ┃┫┫
// ┗┻┛ ┗┻┛
//
// ━━━━━━感觉萌萌哒━━━━━━ // Author : WhyWhy
// Created Time : 2015年09月21日 星期一 23时30分54秒
// File Name : F.cpp #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h> using namespace std; const int MaxN=;
const int MaxNode=; int N; struct Chair_Tree
{
int Tcou;
int TreeRoot[MaxN];
int lson[MaxNode],rson[MaxNode];
int BIT[MaxNode]; void insert(int old,int ne,int id)
{
old=TreeRoot[old]; int newRoot=Tcou++;
int L=,R=N,M; TreeRoot[ne]=newRoot;
BIT[newRoot]=max(id,BIT[old]);
while(R>L)
{
M=(L+R)>>;
if(id<=M)
{
lson[newRoot]=Tcou++;
rson[newRoot]=rson[old];
newRoot=lson[newRoot];
old=lson[old];
R=M;
}
else
{
lson[newRoot]=lson[old];
rson[newRoot]=Tcou++;
newRoot=rson[newRoot];
old=rson[old];
L=M+;
}
BIT[newRoot]=max(id,BIT[old]);
}
} int query(int ql,int qr,int L,int R,int po)
{
if(ql<=L && qr>=R)
return BIT[po]; int M=(L+R)>>;
int ret=; if(ql<=M) ret=max(ret,query(ql,qr,L,M,lson[po]));
if(qr>M) ret=max(ret,query(ql,qr,M+,R,rson[po])); return ret;
} int query(int tree,int ql,int qr)
{
return query(ql,qr,,N,TreeRoot[tree]);
} int Build(int L,int R)
{
int root=Tcou++; BIT[root]=;
if(L!=R)
{
int M=(L+R)>>;
lson[root]=Build(L,M);
rson[root]=Build(M+,R);
}
return root;
} void init()
{
Tcou=;
TreeRoot[]=Build(,N);
}
}tree; int fa1[MaxN],fa2[MaxN];
int dep1[MaxN],dep2[MaxN]; struct Edge
{
int to,next;
}; Edge E[MaxN*];
int Ecou,head[MaxN]; int fa[MaxN],dep[MaxN],son[MaxN],siz[MaxN],top[MaxN],w[MaxN],fw[MaxN];
int Tcou; void init()
{
Ecou=;
Tcou=;
w[]=; //!!!
fw[]=; //!!!
top[]=; //!!!
memset(head,-,sizeof(head));
} void addEdge(int u,int v)
{
E[Ecou].to=v;
E[Ecou].next=head[u];
head[u]=Ecou++;
} void dfs1(int u,int pre,int d)
{
int v; dep[u]=d;
fa[u]=pre;
siz[u]=;
son[u]=-; for(int i=head[u];i!=-;i=E[i].next)
if(E[i].to!=pre)
{
v=E[i].to;
dfs1(v,u,d+);
siz[u]+=siz[v]; if(son[u]==- || siz[son[u]]<siz[v])
son[u]=v;
}
} void dfs2(int u)
{
if(son[u]==-)
return; top[son[u]]=top[u];
w[son[u]]=++Tcou;
fw[w[son[u]]]=son[u]; dfs2(son[u]); int v; for(int i=head[u];i!=-;i=E[i].next)
if(E[i].to!=son[u] && E[i].to!=fa[u])
{
v=E[i].to;
top[v]=v;
w[v]=++Tcou;
fw[w[v]]=v; // !!! dfs2(v);
}
} int query(int tr,int u)
{
int f=top[u];
int ret; while((ret=tree.query(tr,w[f],w[u]))==)
{
u=fa[f];
f=top[u];
} return fw[ret];
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout); int Q;
int a,b;
int t; while(~scanf("%d %d",&N,&Q))
{
t=;
tree.init();
init();
fa1[]=fa2[]=;
dep1[]=dep2[]=; for(int i=;i<=N;++i)
{
scanf("%d",&a);
addEdge(a,i);
addEdge(i,a);
dep1[i]=dep1[a]+;
}
dfs1(,-,);
dfs2(); tree.insert(,,);
for(int i=;i<=N;++i)
{
scanf("%d",&a);
dep2[i]=dep2[a]+;
tree.insert(a,i,w[i]);
} while(Q--)
{
scanf("%d %d",&a,&b);
a=(a+t)%N+;
b=(b+t)%N+;
t=query(b,a);
printf("%d %d %d\n",t,dep1[a]-dep1[t]+,dep2[b]-dep2[t]+);
}
} return ;
}
(中等) Hiho 1232 Couple Trees(15年北京网络赛F题),主席树+树链剖分。的更多相关文章
- hihoCoder #1388 : Periodic Signal ( 2016 acm 北京网络赛 F题)
时间限制:5000ms 单点时限:5000ms 内存限制:256MB 描述 Profess X is an expert in signal processing. He has a device w ...
- acm 2015北京网络赛 F Couple Trees 树链剖分+主席树
Couple Trees Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/problemset/problem/123 ...
- Hiho 1232 北京网络赛 F Couple Trees
给两颗标号从1...n的树,保证标号小的点一定在上面.每次询问A树上的x点,和B树上的y点同时向上走,最近的相遇点和x,y到这个点的距离. 比赛的时候想用倍增LCA做,但写渣了....后来看到题解是主 ...
- 2015北京网络赛 F Couple Trees 暴力倍增
Couple Trees Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/problemset/problem/123 ...
- acm 2015北京网络赛 F Couple Trees 主席树+树链剖分
提交 题意:给了两棵树,他们的跟都是1,然后询问,u,v 表 示在第一棵树上在u点往根节点走 , 第二棵树在v点往根节点走,然后求他们能到达的最早的那个共同的点 解: 我们将第一棵树进行书链剖,然后第 ...
- 北京网赛I题 hiho1391 (树状数组、区间覆盖最大值问题)
题目链接:http://hihocoder.com/problemset/problem/1391 题意:A国和B国向对方分别投射N枚和M枚导弹(发射时间,飞行时间,伤害值),同时两国各自都有防御系统 ...
- hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题
题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给 ...
- 2015北京网络赛B题 Mission Impossible 6
借用大牛的一张图片:模拟 #include<cstdio> #include<cmath> #include<cstring> #include<algori ...
- 2015北京网络赛A题The Cats' Feeding Spots
题意:给你一百个点,找个以这些点为中心的最小的圆,使得这个圆恰好包含了n个点,而且这个圆的边界上并没有点 解题思路:暴力枚举每个点,求出每个点到其他点的距离,取第n大的点,判断一下. #include ...
随机推荐
- .net网站报错:对象的当前状态使该操作无效
微软在2011年12月29号发布的2011年最后一个更新让哥哥为程序出现的异常头痛了一天. 这个异常在页面数据量小的时候并不会触发,只在页面数据量大的情况下才会出现,开始解决起来让人无从下手,最后才发 ...
- 【转】4G手机打电话为什么会断网 4G上网和通话不能并存原因分析
与2G/3G相比,4G最大的特色就是提供了超过100Mbps的峰值速率,既然速度都可以秒掉20M的光纤固网了,那用来语音通话不就更是小菜一碟了吗?很遗憾,问题就出现在了这里. 由于目前的LTE网络(4 ...
- Ant 参考
http://ant.apache.org/manual/Tasks/exec.html Exec Description Executes a system command. When the os ...
- Hibernate 系列教程6-双向多对多
双向多对多inverse配置 如果关系两边都使用默认inverse=false配置,表示关系两边都可以管理中间表的数据 关系其中一边设置inverse=true配置,表示自己放弃管理中间表关系,由对方 ...
- 在DLL中导出另一静态库中的函数
开发环境: win7_x64.VS2013 应用场景: 动态库A依赖动态库B,而动态库B又使用了静态库C:有些情况下,我们需要将C从B里面导出,然后提供给A使用. 正文: Step1: 1.新建测试静 ...
- cfedu/A/求和
题目连接 思路: 用数组直接标记2^n,n属于(0~~31);用LL或者INT都可以,不会爆.但是ans要用LL. #include <set> #include <map> ...
- Element type "bean" must be followed by either attribute specifications, ">" or "/>".
在这里其他内容就省了,错在,<bean id="bpcsU1gblDAO"class="dao.jk.bpcs.impl.BpcsU1gblDaoImpl" ...
- 河南多校大一训练赛 C 青蛙的约会
题目链接:http://acm.hust.edu.cn/vjudge/contest/125004#problem/C 密码:acm Description 两只青蛙在网上相识了,它们聊得很开心,于是 ...
- VS2013编译FileZilla0.9.44
2014年,FileZilla更新了一下,到了44版本了,貌似也是用VS2013的工程做的项目,所以下载了server的安装包,然后安装SourceCode即可(需要安装InterFace,是安装必选 ...
- java开发第一天
今天是项目开始的时间,整体来说还是算顺利的.提前分好组,然后是听课时可以有人帮忙占座位的,感觉上是挺好的. 项目开发的难度看了看,由于有了第一次MFC开发的经验,所以这次听课感觉非常的有目标性,而且总 ...