提交

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

解:

我们将第一棵树进行书链剖,然后第二棵树采用主席树,他的信息来自他的父亲节点,每个点存他在第一棵树 树链剖分后的位置,这样我们每次查询uv的时候我们只要 我们选取u和top[u]这段区间在主席树v这颗树上找,在这个区间能取到的最大值,一旦存在,这个最大值就我们要的,这个点保存着他到根节点这条路上所有点在第一棵树剖分后的位置

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <string.h>
using namespace std;
const int maxn=;
const int MMAXN=*;
int H[maxn],to[maxn*],nx[maxn*],numofE;
int son[maxn],depth[maxn],fa[maxn],num[maxn],top[maxn];
int p[maxn],fp[maxn],pos,sizoftree;
int Ls[MMAXN],Rs[MMAXN],Mav[MMAXN],T[maxn],depth2[maxn];
void init(int n)
{
sizoftree=pos=numofE=;
for(int i=; i<=n; i++)H[i]=;
T[]=Ls[]=Rs[]=Mav[]=sizoftree=;
}
void add(int u,int v)
{
numofE++;
to[numofE]=v;
nx[numofE]=H[u];
H[u]=numofE;
} void dfs(int cur, int per, int dep)
{ depth[cur]=dep;
son[cur]=-;
fa[cur]=per;
num[cur]=;
for(int i=H[cur]; i; i=nx[i])
{
int tt=to[i];
if(tt==per)continue;
dfs(tt,cur,dep+);
num[cur]+=num[tt];
if(son[cur]==- || num[ son[cur] ]<num[tt]) son[cur]=tt;
}
}
void finde(int cur, int per, int tp)
{
top[cur]=tp;
pos++;
p[cur]=pos;
fp[pos]=cur;
if(son[cur]!=-) finde(son[cur],cur,tp);
for(int i=H[cur]; i; i=nx[i])
{
int tt=to[i];
if(tt==per||tt==son[cur])continue;
finde(tt,cur,tt);
}
}
void insert(int L, int R, int K,int pre ,int &x)
{
x=++sizoftree;
Ls[x]=Ls[pre];
Rs[x]=Rs[pre];
Mav[x]=max( Mav[pre],K);
if(L==R)return ;
int mid=(L+R)>>;
if(K<=mid)insert(L,mid,K,Ls[pre],Ls[x]);
else insert(mid+,R,K,Rs[pre],Rs[x]);
}
int cL,cR;
int query(int L, int R,int root)
{
if(cL<=L&&R<=cR)return Mav[root];
if(Mav[root]==)return ;
int mid=(L+R)>>;
int a1=,a2=;
if(cL<=mid)a1=query(L,mid,Ls[root]);
if(cR>mid)a2=query(mid+,R,Rs[root]);
return max(a1,a2);
}
int solve(int u, int v,int n)
{
int fu=top[u];
int ret;
while(true)
{
cL=p[fu];cR=p[u];
ret=query(,n,T[v]);
if(ret)break;
u=fa[fu];
fu=top[u];
}
return fp[ret];
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)==)
{
init(n);
for(int i=; i<=n; i++)
{
int u;
scanf("%d",&u);
add(i,u); add(u,i);
}
dfs(,,);
finde(,,);
depth2[]=;
insert(,n,,T[],T[]);
for(int i=; i<=n; i++)
{
int u;
scanf("%d",&u);
depth2[i]=depth2[u]+;
insert(,n,p[i],T[u],T[i]);
}
int ans=;
for(int i=; i<m; i++)
{
int u,v;
scanf("%d%d",&u,&v);
u=(u+ans)%n+;
v=(v+ans)%n+;
ans=solve(u,v,n);
printf("%d %d %d\n",ans,depth[u]-depth[ans]+,depth2[v]-depth2[ans]+);
} }
return ;
}

acm 2015北京网络赛 F Couple Trees 主席树+树链剖分的更多相关文章

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

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

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

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

  3. (中等) Hiho 1232 Couple Trees(15年北京网络赛F题),主席树+树链剖分。

    "Couple Trees" are two trees, a husband tree and a wife tree. They are named because they ...

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

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

  5. 2015 北京网络赛 E Border Length hihoCoder 1231 树状数组 (2015-11-05 09:30)

    #1231 : Border Length 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 Garlic-Counting Chicken is a special spe ...

  6. 2015北京网络赛 Couple Trees 倍增算法

    2015北京网络赛 Couple Trees 题意:两棵树,求不同树上两个节点的最近公共祖先 思路:比赛时看过的队伍不是很多,没有仔细想.今天补题才发现有个 倍增算法,自己竟然不知道.  解法来自 q ...

  7. 2015北京网络赛 D-The Celebration of Rabbits 动归+FWT

    2015北京网络赛 D-The Celebration of Rabbits 题意: 给定四个正整数n, m, L, R (1≤n,m,L,R≤1000). 设a为一个长度为2n+1的序列. 设f(x ...

  8. 2015北京网络赛 J Scores bitset+分块

    2015北京网络赛 J Scores 题意:50000组5维数据,50000个询问,问有多少组每一维都不大于询问的数据 思路:赛时没有思路,后来看解题报告也因为智商太低看了半天看不懂.bitset之前 ...

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

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

随机推荐

  1. js中文输入法字符串截断

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. Linux常见问题整理

    1. 操作系统应该要控制硬件的哪些单元? 运算单元.控制单元.寄存器组.总线接口单元.输入/输出接口单元. 2. 一个较为完整的操作系统应该包含哪些部分? 比较完整的操作系统应该包含两个组件,一个是核 ...

  3. Android查看文件大小

    查看当前路径下的各个挂载模块的大小及剩余量(例如在根目录执行) df #输出 Filesystem Size Used Free Blksize /sys/fs/cgroup .0K /mnt/ase ...

  4. java基础---->String和MessageFormat的format方法

    这里介绍一下String和MessageFormat中的format方法的差异以及实现原理. String与MessageFormat的说明 一.两者的使用场景 String.format:for l ...

  5. HashTab---Windows资源管理器的文件属性窗口中添加了一个叫做”文件校验”的标签

    HashTab 是一个优秀的 Windows 外壳扩展程序,它在 Windows 资源管理器的文件属性窗口中添加了一个叫做”文件校验”的标签.该标签可以帮助你方便地计算文件的 MD5.SHA1 与 C ...

  6. [原]Jenkins(十九) jenkins再出发之jenkins邮件通知

    1.下载插件: 2.配置插件: 3.邮件插件配置 4.设置触发器:

  7. vue利用vue ui命令创建项目

    上次用git bash,用create 命令创建vue项目,这是玩个炫酷的------vue ui (前提是有安装node.js). 在目标文件  vue ui 可以看到他在8000端口出现了一个gu ...

  8. 一些关于SQL优化的总结

    由于这个项目一直都是mysql所以写点mysql的 1.数据存储引擎的选择,MyISAM 和 InnoDB 的选择 InnoDB 一般都会选择这个,但是如果真的涉及到一些不涉及增删的表,可以考虑下My ...

  9. ps把照片背景变成透明[原为白色或其他颜色]

    在第六步:魔法棒选中之后,按delete键,即可!!! 注意:背景变成透明颜色,需要把照片格式变成png 就可以了!!!

  10. DIOCP3-粘包处理

    DIOCP3-粘包处理   什么是粘包: 第一次发送  12345, 第二次发送abcde, 底层socket可能会一次性进行发送12345abcde,或者对方可能一次性进行了接收,那接收的时候,你可 ...