题目概括

题目描述

这个游戏会给出你一棵树,这棵树有\(N\)个节点,根结点是\(R\),系统会选中\(M\)个点\(P_1,P_2...P_M\).

要Imakf回答有多少组点对\((u_i,v_i)\)的最近公共祖先是\(P_i\)。

Imakf是个小蒟蒻,他就算学了LCA也做不出,于是只好求助您了。

Imakf毕竟学过一点OI,所以他允许您把答案模 \((10^9+7)\)

输入输出格式

输入格式

第一行 \(N , R , M\) 此后\(N-1\)行 每行两个数\(a,b\) 表示\(a,b\)之间有一条边 此后\(1\)行 \(M\)个数 表示\(P_i\)

输出格式

\(M\)行,每行一个数,第\(i\)行的数表示有多少组点对\((u_i,v_i)\)的最近公共祖先是\(P_i\)

输入输出样例

输入样例 #1
7 1 3
1 2
1 3
2 4
2 5
3 6
3 7
1 2 4
输出样例 #1
31
7
1

样例解释

样例1

对于询问1

\[(1,1) (1,2) (1,3) (1,4) (1,5) (1,6) (1,7) \\\\
(2,1) (2,3) (2,6) (2,7) (3,1) (3,2) (3,4) (3,5) \\\\
(4,1) (4,3),(4,6) (4,7) \\\\
(5,1) (5,3) (5,6) (5,7) \\\\
(6,1) (6,2) (6,4) (6,5) \\\\
(7,1) (7,2) (7,4) (7,5)
\]

共31组

询问2

\[(2,2) (2,4) (2,5)\\\\
(4,2) (4,5) \\\\
(5,2) (5,4)
\]

共7组

对于询问3

\[(4,4)
\]

共1组

\[N \leq 10000,M \leq 50000
\]


解题报告

题意理解

  1. 就是问你有多少个数对,以\(P_i\)为最近公共祖先.

  2. 然后有\(m\)次查询

算法解析

这道题目,其实只考到了\(Lca\)概念,然后就没有然后了.

\[满足Lca(a,b)=x条件,合法数对为(a,b)\\
\]

我们分析一下,满足条件的数对,有哪些特性.

  1. \((a,b)\)不同属于x一个子节点的子树,反例如下

  2. \((a,b)\)必须都属于x的子树.反例如下

  3. \((a,b)\)分别属于,\(x\)不同的儿子的子树节点.正确如下所示

  4. \((a,b)\)之中有一个是\(x\),另外一个是\(x\)的子树节点

  5. \((a,b)\)都是\(x\).懒得画图了

因此,我们总结得出以上规律.

然后如何统计个数呢.

\[size[x][i]表示x的第i个儿子节点的子树大小,包括儿子节点i \\\\k表示x的儿子节点总数 \\\\Size[x]表示x的子树节点个数,包括x
\]

然后我们开始分类讨论.

  1. \((a,b)\)都是\(x\)子树节点.

\[size[x][1] \times size[x][2] \times 2 \quad 其中一类\\\\任选两个儿子节点,子树相乘,再加上有序数对,所以乘以2 \\\\\sum_{i=1}^{k}{\sum_{j=1}^{k}size[x][i] \times size[x][j]} \\\\\Rightarrow \sum_{i=1}^{k}{size[x][i] \times (Size[x]-1)} \\\\\Rightarrow (Size[x]-1) \times (Size[x]-1)
\]

然后重复计算了\(a=b\)的情况.

\[\sum_{i=1}^{k}{size[x][i]^2}
\]

于是最后要记得减去.

  1. \((a,b)\)中有节点是\(x\)

于是我们很容易得出.

\[2 \times Size[x] -1 \quad -1是因为(x,x)算了两次
\]

综上所述,我们得出答案为.

\[ans=(2 \times Size[x]-1)+(Size[x]-1)^2-(\sum_{i=1}^{k}{size[x][i]^2})
\]


代码解析

#include <bits/stdc++.h>
using namespace std;
const int N=10000+20,Mod=1e9+7;
int n,r,m,size[N],root;
long long ans[N],sum[N];
vector<int> g[N];
inline void dfs(int x,int fa)
{
size[x]=1;
for(int y:g[x])
{
if (y==fa)
continue;
dfs(y,x);
size[x]+=size[y];
sum[x]+=size[y]*size[y];
sum[x]%=Mod;
}
ans[x]=(size[x]*size[x]-sum[x])%Mod;
}
inline void init()
{
scanf("%d%d%d",&n,&r,&m);
for(int i=1; i<n; i++)
{
int a,b;
scanf("%d%d",&a,&b);
g[a].push_back(b);
g[b].push_back(a);
}
dfs(r,r);
while(m--)
{
int x;
scanf("%d",&x);
printf("%lld\n",ans[x]);
}
}
signed main()
{
init();
return 0;
}

洛谷P5002 专心OI - 找祖先的更多相关文章

  1. P5002 专心OI - 找祖先

    P5002 专心OI - 找祖先 给定一棵有根树(\(n \leq 10000\)),\(M \leq 50000\) 次询问, 求以 \(x\) 为 \(LCA\) 的点对个数 错误日志: 看下面 ...

  2. luogu P5002 专心OI - 找祖先

    题目描述 这个游戏会给出你一棵树,这棵树有NN个节点,根结点是RR,系统会选中MM个点P_1,P_2...P_MP 1 ​ ,P 2 ​ ...P M ​ ,要Imakf回答有多少组点对(u_i,v_ ...

  3. 【洛谷 5002】专心OI - 找祖先 (树上计数)

    专心OI - 找祖先 题目背景 \(Imakf\)是一个小蒟蒻,他最近刚学了\(LCA\),他在手机\(APP\)里看到一个游戏也叫做\(LCA\)就下载了下来. 题目描述 这个游戏会给出你一棵树,这 ...

  4. [luogu5002]专心OI - 找祖先

    [传送门] 我们还是先将一下算法的步骤,待会再解释起来方便一点. 算法步骤 首先我们算出每个子树的\(size\). 我们就设当前访问的节点 然后我们就得到了当前这个节点的答案是这个树整个的\(siz ...

  5. 【BZOJ4566_洛谷3181】[HAOI2016]找相同字符(SAM)

    自己yy的方法yyyyyyyy着就A了,写篇博客庆祝一下. 题目: 洛谷3181 分析: SAM(可能是)模板题(不会SAM的同学戳我:[知识总结]后缀自动机的构建). 对\(s1\)建出SAM,用\ ...

  6. 【洛谷P3398】仓鼠找sugar

    画个图就能多少看出些规律 证明借鉴一下大牛的题解: 设从A到B,经过的深度最小的点为X 同理,C,D的为Y 题目是一个点从A出发到B 一个从C出发到D 那么从A到B可以分解成 先从A到X 再从X到B. ...

  7. 洛谷 P3092 [USACO13NOV]没有找零No Change

    题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...

  8. 洛谷P3092 [USACO13NOV]没有找零No Change

    P3092 [USACO13NOV]没有找零No Change 题目描述 Farmer John is at the market to purchase supplies for his farm. ...

  9. 【洛谷P3901】数列找不同

    题目大意:给定一个长度为 N 的序列,每个点被染了一个颜色.现有 M 个询问,每个询问查询区间 [l,r] 内的点是否颜色都是不同的. 题解:莫队裸题. 直接维护区间颜色数,用 cnt[] 记录下区间 ...

随机推荐

  1. KMeans聚类

    常用的聚类方法: ①分裂方法: K-Means算法(K-平均).K-MEDOIDS算法(K-中心点).CLARANS算法(基于选择的算法) ②层次分析方法: BIRCH算法(平衡迭代规约和聚类).CU ...

  2. CX ONE 不能全屏

    兼容性  win7 以管理员方式运行 1. 打开CX-Programmer,选择“工具”——“选项”:2. 点击“通用”选项卡,选择“高级”:3. 勾选“当下一次启动CX-Programmer时不显示 ...

  3. CentOS 7 安装wordpress

    1.安装php 要安装php 7,必须使用下面的命令在Centos7系统上安装并启用epel和remi存储库. 输入一下代码, yum install http://rpms.remirepo.net ...

  4. ROS学习(二)运行keyboard

    1.ssh连接机器人 ./dora*.sh 启动roscore,相当于启动ros系统 roscore 2.另启终端,也就意味着重新ssh连接机器人, ./dora*.sh 运行wheel驱动 rosr ...

  5. Android 8.1 MTK6739修改文档

    1. 信息-设置-通知-重要程度-中(不发出提示音),非锁屏界面下无提示通知框弹出 vendor/mediatek/proprietary/packages/apps/SystemUI/src/com ...

  6. Word 查找替换高级玩法系列之 -- 将换行符替换成回车符

    我们从网上Copy过来的很多Word文档,里面使用的都是换行符,也就是我们常说的软回车,它显示为一个向下的箭头.这些符号不仅碍眼,而且会影响我们后期的排版,尤其是对段落的排版,因为Word里面的段落只 ...

  7. php之简单算法

    选择排序 方式:先让第一位与其他位比较大小找到最小的数字,然后是第二位与除第一位的其他位比较大小找出第二位,依此类推 $arr = [2,45,12,67,33,5,23,132,46]; for ( ...

  8. 20190621-N皇后

    N皇后 难度分类 困难 题目描述 n皇后问题研究的是如何将 n个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回所有不同的 n  ...

  9. Linux自动运维工具Ansible的使用

    Linux自动运维工具Ansible的使用 我们熟悉这个工具后, 可以很轻松的安装k8s. 一.介绍 ansible - run a task on a target host(s) Ansible是 ...

  10. (十三)使用handler实现登录验证

    一.Handel概念 J2EE Web 服务中的Handler技术特点非常像Servlet技术中的Filter.我们知道,在Servlet中,当一个HTTP到达服务端时,往往要经过多个Filter对请 ...