1681 公共祖先

基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
 

有一个庞大的家族,共n人。已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边)。

在另一个未知的平行宇宙,这n人的祖辈关系仍然是树形结构,但他们相互之间的关系却完全不同了,原来的祖先可能变成了后代,后代变成的同辈……

两个人的亲密度定义为在这两个平行宇宙有多少人一直是他们的公共祖先。

整个家族的亲密度定义为任意两个人亲密度的总和。

Input
第一行一个数n(1<=n<=100000)
接下来n-1行每行两个数x,y表示在第一个平行宇宙x是y的父亲。
接下来n-1行每行两个数x,y表示在第二个平行宇宙x是y的父亲。
Output
一个数,表示整个家族的亲密度。
Input示例
5
1 3
3 5
5 4
4 2
1 2
1 3
3 4
1 5
Output示例
6
/*
51 nod 1681 公共祖先 (主席树+dfs序) problem:
给你两棵树, 两个节点之间的值定义为在两个棵树中有多少一直是它们的公共祖先
求任意两个点的亲密度的总和 solve:
问题可以转换成每个点能够成为多少次公共祖先. 如果lca一直是a,b的公共祖先, 那么
a,b一定在lca的子树中. 所以找出两棵树中lca点的子树中的相同点的个数,就能计算出多少对点
在两棵树中都有lca这个公共祖先. 先处理出a树的dfs序,然后用其作为b树中dfs序的值. 在a树中,如果u在lca的子树中,那么它的序号
大于dfa[lca]小于等于eda[lca],即进出值. 所以在b树的lca的子树中找出序号在[dfa[lca],eda[lca]]
之间的个数(可以主席树维护), 就是lca子树所含相同点的个数. hhh-2016/09/16-11:36:14
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <map>
//#define lson i<<1
//#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define scanfi(a) scanf("%d",&a)
#define scanfs(a) scanf("%s",a)
#define scanfl(a) scanf("%I64d",&a)
#define scanfd(a) scanf("%lf",&a)
#define key_val ch[ch[root][1]][0]
#define eps 1e-7
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const ll mod = 1e9+7;
const int maxn = 100010;
const double PI = acos(-1.0); template<class T> void read(T&num)
{
char CH;
bool F=false;
for(CH=getchar(); CH<'0'||CH>'9'; F= CH=='-',CH=getchar());
for(num=0; CH>='0'&&CH<='9'; num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p)
{
if(!p)
{
puts("0");
return;
}
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
} struct Edge
{
int to,next;
};
Edge edge[maxn*2];
int tot,head[maxn];
int in[maxn];
int cnt;
void ini()
{
tot = 0;
cnt = 0;
memset(in,0,sizeof(in));
memset(head,-1,sizeof(head));
}
void add_edge(int u,int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
int dfa[maxn],dfb[maxn],ta[maxn],tb[maxn];
int eda[maxn],edb[maxn];
void dfs(int u,int pre,int flag)
{
if(!flag) dfa[u] = ++ cnt, ta[u] = cnt;
else dfb[u] = ++ cnt, tb[cnt] = ta[u];
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if(v == pre)continue;
dfs(v,u,flag);
}
if(!flag) eda[u] = cnt;
else edb[u] = cnt;
} int toa;
int lson[maxn * 30],rson[maxn * 30] ;
ll c[maxn * 30]; int build(int l,int r)
{
int root = toa ++ ;
c[root] = 0;
if(l != r)
{
int mid = (l+r) >> 1;
build(l,mid);
build(mid+ 1,r);
}
return root ;
}
int n;
int update(int root,int pos,ll val)
{
int newroot = toa ++ ,tmp = newroot;
c[newroot ] = c[root] + val;
int l = 1,r = n; while(l < r)
{
int mid = (l+r) >> 1;
if(pos <= mid)
{
lson[newroot] = toa ++ ,rson[newroot] = rson[root];
newroot = lson[newroot],root = lson[root];
r = mid;
}
else
{
rson[newroot] = toa ++ ,lson[newroot] = lson[root];
newroot = rson[newroot] ,root = rson[root];
l = mid + 1;
}
c[newroot] = c[root] + val;
}
return tmp;
} ll query(int root1,int root2,int la,int ra,int l,int r)
{
if(l >= la && r <= ra)
{
return c[root2] - c[root1];
}
int mid = (l + r) >> 1;
ll ans = 0;
if(la <= mid)
{
ans += query(lson[root1],lson[root2],la,ra,l,mid);
}
if(ra > mid)
{
ans += query(rson[root1],rson[root2],la,ra,mid+1,r);
}
return ans;
} void cal(int flag)
{
int u,v;
ini();
for(int i = 1; i < n; i++)
{
read(u),read(v);
add_edge(u,v);
add_edge(v,u);
in[v] ++ ;
}
for(int i = 1; i <= n;i++)
{
if(!in[i])
{
dfs(i,-1,flag);
break;
}
}
}
int T[maxn];
int main()
{
// freopen("in.txt","r",stdin);
read(n);
toa = 0;
cal(0);
cal(1);
T[0] = build(1,n);
for(int i = 1;i <= n;i++)
{
T[i] = update(T[i-1],tb[i],1);
}
ll ans = 0;
for(int i = 1;i <= n;i++)
{
int l = dfb[i],r = edb[i];
ll t = query(T[l],T[r],dfa[i],eda[i],1,n);
ans += 1LL*t*(t-1)/2;
}
printf("%I64d\n",ans);
return 0;
}

  

51 nod 1681 公共祖先 (主席树+dfs序)的更多相关文章

  1. 「10.19」最长不下降子序列(DP)·完全背包问题(spfa优化DP)·最近公共祖先(线段树+DFS序)

    我又被虐了... A. 最长不下降子序列 考场打的错解,成功调了两个半小时还是没A, 事实上和正解的思路很近了,只是没有想到直接将前$D$个及后$D$个直接提出来 确实当时思路有些紊乱,打的时候只是将 ...

  2. 【BZOJ1803】Spoj1487 Query on a tree III 主席树+DFS序

    [BZOJ1803]Spoj1487 Query on a tree III Description You are given a node-labeled rooted tree with n n ...

  3. BZOJ3772 精神污染 【主席树 + dfs序】

    题目 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是集经济和文化于一体的一大地区,是日本西部门户,海 ...

  4. 刷题总结——谈笑风生(主席树+dfs序的应用)

    题目: Description 设T 为一棵有根树,我们做如下的定义:• 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道高明到哪里去了”.• 设a 和 b 为 T 中的两个不同 ...

  5. bzoj 3772 精神污染 主席树+dfs序

    精神污染 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 637  Solved: 177[Submit][Status][Discuss] Descri ...

  6. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  7. 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)

    http://www.spoj.com/problems/COT/ (速度很快,排到了rank6) 这题让我明白了人生T_T 我知道我为什么那么sb了. 调试一早上都在想人生. 唉. 太弱. 太弱. ...

  8. BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]

    传送门 题意:查询树上根节点值*子树中权值和$\le m$的最大数量 最大值是多少 求$DFS$序,然后变成区间中和$\le m$最多有几个元素,建主席树,然后权值线段树上二分就行了 $WA$:又把边 ...

  9. BZOJ_1803_Spoj1487 Query on a tree III_主席树+dfs序

    BZOJ_1803_Spoj1487 Query on a tree III_主席树 Description You are given a node-labeled rooted tree with ...

随机推荐

  1. Linux下I/O多路转接之select --fd_set

    fd_set 你终于还是来了,能看到这个标题进来的,我想,你一定是和我遇到了一样的问题,一样的疑惑,接下来几个小时,我一定竭尽全力,写出我想说的,希望也正是你所需要的: 关于Linux下I/O多路转接 ...

  2. Python 实现队列

    操作 Queue() 创建一个空的队列 enqueue(item) 往队列中添加一个item元素 dequeue() 从队列头部删除一个元素 is_empty() 判断一个队列是否为空 size() ...

  3. 201421123042 《Java程序设计》第7周学习总结

    1. 本周学习总结 1.1 思维导图:Java图形界面总结 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模型中最重要的几个关键词. 事件源 事件对象 事件监听器 事件适合配器 1.2 ...

  4. IDEA之Jrebel插件激活

    问题: 码农日常中,热部署是必不可少的,而jrebel插件很好的实现热部署功能. IDEA下载jrebel插件,可以免费试用15天,但之后就无法使用.因为Jrebel是收费的. 解决方法: 楼主也是百 ...

  5. 电梯模拟C++

    1.问题描述与要求 模拟某校九层教学楼的电梯系统.该楼有一个自动电梯,能在每层停留,其中第一层是大楼的进出层,即是电梯的"本垒层",电梯"空闲"时,将来到该层候 ...

  6. 阿里云API网关(9)常见问题

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  7. 基于python的统计公报关键数据爬取

    # -*- coding: utf-8 -*- """ Created on Wed Nov 8 14:23:14 2017 @author: 123 "&qu ...

  8. JSON(四)——异步请求中前后端使用Json格式的数据进行交互

    json格式的数据广泛应用于异步请求中前后端的数据交互,本文主要介绍几种使用场景和使用方法. 一,json格式字符串 <input type="button" id=&quo ...

  9. JAVAFX-5 开发应用

    fx 属性与布局 属性与布局是一个具备gui开发能力的开发者,快速进入开发必备的知识储备,下面简单说一说常用的属性,与布局 颜色 颜色 在 javafx.scene.paint.Color 类中提供了 ...

  10. 解析 Javascript - this

    在函数中 this 到底取何值,是在函数真正被调用执行的时候确定下来的,函数定义的时候确定不了.  因为 this 的取值是执行上下文环境的一部分,每次调用函数,都会产生一个新的执行上下文环境.当你在 ...