给两颗标号从1...n的树,保证标号小的点一定在上面。每次询问A树上的x点,和B树上的y点同时向上走,最近的相遇点和x,y到这个点的距离。

比赛的时候想用倍增LCA做,但写渣了。。。。后来看到题解是主席树就写了一发

呆马:

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#define inf 1000000007
#define maxn 100020
#define maxm 4200 using namespace std; int fa[maxn],ga[maxn],ll[maxn],rr[maxn],dep[maxn],gap[maxn];
int n,m,cnt; struct node
{
node *lc, *rc;
int key, cov;
node(){
key=;
cov=;
lc=rc=NULL;
}
}; struct ChairManTree
{
node *tree,*rot[maxn];
int tot;
node *new_node(){ return &tree[++tot];}
node *build(int l, int r)
{
node *now=new_node();
now->cov=now->key=;
if (l==r) return now;
int mid=(l+r)>>;
now->lc=build(l,mid);
now->rc=build(mid+,r);
return now;
} void down(node *p)
{
if (p->cov)
{
node *nl=new_node();
node *nr=new_node();
*nl=*p->lc;
*nr=*p->rc;
nl->key=max(p->lc->key,p->cov);
nl->cov=max(p->lc->cov,p->cov);
nr->key=max(p->rc->key,p->cov);
nr->cov=max(p->rc->cov,p->cov);
p->lc=nl;
p->rc=nr;
p->cov=;
}
} node *change(node *p, int l, int r, int ll, int rr, int x)
{
node *now=new_node();
if (ll<=l && r<=rr)
{
*now=*p;
now->key=max(now->key,x);
now->cov=max(now->cov,x);
return now;
}
down(p);
*now=*p;
int mid=(l+r)>>;
if (ll<=mid) now->lc=change(p->lc, l, mid, ll, rr, x);
if (rr>mid) now->rc=change(p->rc, mid+, r, ll, rr, x);
return now;
} int query(node *now, int l, int r, int x)
{
if (l==r) return now->key;
down(now);
int mid=(l+r)>>;
if (x<=mid) return query(now->lc, l, mid, x);
else return query(now->rc, mid+, r, x);
} void write(node *now,int l,int r)
{
if (l==r)
{
cout<<now->key;
return ;
}
down(now);
int mid=(l+r)>>;
write(now->lc,l,mid);
write(now->rc,mid+,r);
} void init(int n)
{
tree=new node[n*];
tot=;
}
void clear()
{
delete [] tree;
}
}s; vector<int> e[maxn]; void dfs(int x)
{
ll[x]=++cnt;
int n=e[x].size();
for (int i=;i<n;i++)
{
int k=e[x][i];
dfs(k);
}
rr[x]=cnt;
} int main()
{
//freopen("F.in","r",stdin);
while (scanf("%d%d",&n,&m)!=EOF)
{
s.init(n);
fa[]=ga[]=;
dep[]=gap[]=;
for (int i=;i<=n;i++) e[i].clear();
for (int i=;i<=n;i++) scanf("%d",&fa[i]), e[fa[i]].push_back(i), dep[i]=dep[fa[i]]+;
for (int i=;i<=n;i++) scanf("%d",&ga[i]), gap[i]=gap[ga[i]]+;
cnt=;
dfs(); s.rot[]=s.build(,n); for (int i=;i<=n;i++)
s.rot[i]=s.change(s.rot[ga[i]],,n,ll[i],rr[i],i);
int x,y,ans=;
for (int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
x=(x+ans)%n+, y=(y+ans)%n+;
ans=s.query(s.rot[y],,n,ll[x]);
printf("%d %d %d\n",ans,dep[x]-dep[ans]+, gap[y]-gap[ans]+);
}
s.clear();
}
return ;
}

couple tree

Hiho 1232 北京网络赛 F Couple Trees的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. HDU 5037 Frog(2014年北京网络赛 F 贪心)

    开始就觉得有思路,结果越敲越麻烦...  题意很简单,就是说一个青蛙从0点跳到m点,最多可以跳l的长度,原有石头n个(都仅表示一个点).但是可能跳不过去,所以你是上帝,可以随便在哪儿添加石头,你的策略 ...

  7. 2017北京网络赛 F Secret Poems 蛇形回路输出

    #1632 : Secret Poems 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 The Yongzheng Emperor (13 December 1678 – ...

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

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

  9. 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 ...

随机推荐

  1. 201301 JAVA题目0-1级

    描述 编写一个函数,传入一个int型数组,返回该数组能否分成两组,使得两组中各元素加起来的和相等,并且,所有5的倍数必须在其中一个组中,所有3的倍数在另一个组中(不包括5的倍数),能满足以上条件,返回 ...

  2. springboot+redis

    上篇整合了DB层,现在开始整合缓存层,使用redis. springboot驱动注解,使用spring注入JedisPool便可封装自己的redis工具类. package hello.configu ...

  3. 带你玩转JavaWeb开发之三 -JS插件实战开发

    前提:需要掌握的知识点           填写HTML代码 Element元素中有一个innerHTML属性,这个属性可以填写一段html代码 innerHTML = "<font ...

  4. 小技巧,关于OC打印指针地址和arc下的retaincount

    CFGetRetainCount((__bridge CFTypeRef)self  : 打印retainCount 打印指针的地址(不是指针指向对象的地址):NSLog(@"aStr指针内 ...

  5. C++笔记----构造函数与析构函数(三)

    1.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段:初始化段. 普通计算段 2.对象成员及其初始化 #include<iostream> using ...

  6. easyui 分页 MVC

    View <script type="text/javascript"> var dd; var grid; $(function () { var queryData ...

  7. 浅谈MySQL数据类型

    MySQL 数据类型 MySQL中定义数据字段的类型对你数据库的优化是非常重要的. MySQL支持多种类型,大致可以分为三类:数值.日期/时间和字符串(字符)类型. 一.数值类型 MySQL支持所有标 ...

  8. 理解JAVA - 面向对象(object) - 属性,方法

    理解JAVA - 面向对象(object) - 属性,方法 多态的体现:    向上造型,父类接收子类对象:向上造型:    从父类角度看不到子类独有的方法:面向对象,人类认知世界的方式:生活中每天都 ...

  9. python正则

    1.. 匹配任意除换行符"\n"外的字符:2.*表示匹配前一个字符0次或无限次:3.+或*后跟?表示非贪婪匹配,即尽可能少的匹配,如*?重复任意次,但尽可能少重复:4. .*? 表 ...

  10. Linux 下应用程序最大打开文件数的理解和修改

    运行在Linux系统上的Java程序运行了一段时间后出现"Too many open files"的异常情况. 这种情况常见于高并发访问文件系统,多线程网络连接等场景.程序经常访问 ...