"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题),主席树+树链剖分。的更多相关文章

  1. hihoCoder #1388 : Periodic Signal ( 2016 acm 北京网络赛 F题)

    时间限制:5000ms 单点时限:5000ms 内存限制:256MB 描述 Profess X is an expert in signal processing. He has a device w ...

  2. acm 2015北京网络赛 F Couple Trees 树链剖分+主席树

    Couple Trees Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/problemset/problem/123 ...

  3. Hiho 1232 北京网络赛 F Couple Trees

    给两颗标号从1...n的树,保证标号小的点一定在上面.每次询问A树上的x点,和B树上的y点同时向上走,最近的相遇点和x,y到这个点的距离. 比赛的时候想用倍增LCA做,但写渣了....后来看到题解是主 ...

  4. 2015北京网络赛 F Couple Trees 暴力倍增

    Couple Trees Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/problemset/problem/123 ...

  5. acm 2015北京网络赛 F Couple Trees 主席树+树链剖分

    提交 题意:给了两棵树,他们的跟都是1,然后询问,u,v 表 示在第一棵树上在u点往根节点走 , 第二棵树在v点往根节点走,然后求他们能到达的最早的那个共同的点 解: 我们将第一棵树进行书链剖,然后第 ...

  6. 北京网赛I题 hiho1391 (树状数组、区间覆盖最大值问题)

    题目链接:http://hihocoder.com/problemset/problem/1391 题意:A国和B国向对方分别投射N枚和M枚导弹(发射时间,飞行时间,伤害值),同时两国各自都有防御系统 ...

  7. hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题

    题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给 ...

  8. 2015北京网络赛B题 Mission Impossible 6

    借用大牛的一张图片:模拟 #include<cstdio> #include<cmath> #include<cstring> #include<algori ...

  9. 2015北京网络赛A题The Cats' Feeding Spots

    题意:给你一百个点,找个以这些点为中心的最小的圆,使得这个圆恰好包含了n个点,而且这个圆的边界上并没有点 解题思路:暴力枚举每个点,求出每个点到其他点的距离,取第n大的点,判断一下. #include ...

随机推荐

  1. android:onKeyDown

    android项目中的返回键有时处理不当,会是一个十分麻烦的问题. 在监听物理键时,可以用onKeyDown方法,Activity已经自己有KeyEvent.Callback这个接口了,因为项目有使用 ...

  2. 在Linux下编写php扩展

    以下内容是本人学习过程中的笔记或者心得,如果有什么建议或者意见请在评论中提醒我,谢谢,这篇文章我会定期更新,由浅到深的分享我学PHP扩展历程 或者在学习中有什么问题欢迎交流 1.去PHP官网下载一个源 ...

  3. Inno Setup入门(十四)——替换安装程序和卸载程序的图标

    通常Inno生成的安装文件的图标是一个光盘和显示器,如下图.同时,程序安装好之后,在安装目录下的卸载程序的图标也是一样的,其实我们也可以自己修改. 首先生成的安装文件图标.这个比较简单,只需要在Set ...

  4. 免费 WebOffice使用

    目前WebOffice使用比较多主要有两个公司的产品,分别是江西金格和北京点聚.但是点聚的是免费的,虽然有欠缺之处,但是经过个人修改还是比较好用的,关键一点是,它免费啊! 把一个最主要加载页面,如果读 ...

  5. EditText的一点深入的了解

    最近在开发android下的记事本程序时,频繁的使用EditText控件,折腾来折腾去,算是对其的了解更深入了一些.特将这些收获记录如下: 一.几个属性的介绍 android:gravity=&quo ...

  6. SEO策略与细节:细节决定成败

    昨天展开seo探讨会.听了一场医疗界seo大神的讲座.收益匪浅今天讲他的演讲内容整理出来与大家分享.希望对医疗界的seo带来些帮助.站长们一起成长! 一.首页 1.元标签设置 标题:上海癫痫病医院哪家 ...

  7. MFC DLL中导出函数模板

    //my.h struct AFX_EXT_CLASS B { }; struct AFX_EXT_CLASS C { }; class AFX_EXT_CLASS A { public: templ ...

  8. 购物车CheckBox全选、反选

    注意:不是很完美 //--------------------主布局文件--------------------------------- <LinearLayout xmlns:android ...

  9. IE6下绝对定位元素和浮动元素并列绝对定位元素消失

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. ibdata1文件--缩小mysql数据库的ibdata1文件

    摘要 在MySQL数据库中,如果不指定innodb_file_per_table参数,单独存在每个表的数据,MySQL的数据都会存放在ibdata1文件. mysql ibdata1存放数据,索引等, ...