洛谷P5002 专心OI - 找祖先 树上统计+LCA+次方余项

news/2024/10/22 15:33:24/

洛谷P5002 专心OI - 找祖先


标签

  • LCA
  • 树上统计
  • 次方余项的计算

简明题意

  • 给一颗有根树,再给m个询问,对于某个节点x,有多少对节点的LCA是x

思路

  • 这题非常简单。我们假设要求x的答案。显然,LCA是x的一对节点,
    1. u,v != x,则u,v肯定位于x的不同两颗子树,那么答案显然就是 ∑ 2 ∗ s i z [ u ] ∗ s i z [ v ] \sum 2 * siz[u] * siz[v] 2siz[u]siz[v],其中siz[v]定义为子树v的大小。
    2. uv其中可能等于x的情况。这种情况下,uv其一是x,另一个可以是左右子树中的任意一个,那么答案显然就是siiz[u] * 2 - 1了。
  • 求法:对于siz的大小,直接dfs就能得出了。那么对于1答案应该怎么求呢?难道要求出子树后,然后 o ( n 2 ) o(n^2) o(n2)遍历吗?显然可以稍加优化,比如u有三棵子树,编号1,2,3。1中的答案应该是 2 ∗ s i z [ 1 ] ∗ s i z [ 2 ] + 2 ∗ s i z [ 1 ] ∗ s i z [ 3 ] + 2 ∗ s i z [ 2 ] ∗ s i z [ 3 ] 2*siz[1] *siz[2] + 2 * siz[1] * siz[3] + 2*siz[2]*siz[3] 2siz[1]siz[2]+2siz[1]siz[3]+2siz[2]siz[3],说到这里你想到了啥?这不就是 ( s i z [ 1 ] + s i z [ 2 ] + s i z [ 3 ] ) 2 − s i z [ 1 ] 2 − s i z [ 2 ] 2 − s i z [ 3 ] 2 (siz[1]+siz[2]+siz[3])^2 - siz[1]^2-siz[2]^2 - siz[3]^2 (siz[1]+siz[2]+siz[3])2siz[1]2siz[2]2siz[3]2,然后就可以很容易的在递归中顺便处理掉

注意事项

  • 题目指定了根,dfs时,不仅根时root,入口也应该是root,不要树剖做多了,就默认1是根或者入口

总结

  • 有n个集合,每个集合里的元素个数是a[i],现在问你从集合中选出两个元素有多少种选法?可以参照上面的方法, 元 素 总 个 数 2 − ∑ 每 个 集 合 元 素 个 数 2 元素总个数^2 -\sum 每个集合元素个数^2 22,如果是次方,也是类似的做法,我把他成为“次方余项的计算”

AC代码

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;int n, root, m;
vector<int> g[maxn];long long ans[maxn];int siz[maxn], fa[maxn];
void dfs1(int u, int f)
{fa[u] = f;siz[u] = 1;long long sum = 0;for (auto& v : g[u])if (v != f){dfs1(v, u);siz[u] += siz[v];sum -= siz[v] * siz[v];}ans[u] = sum + (siz[u] - 1) * (siz[u] - 1)  + siz[u] * 2 - 1;
}void solve()
{scanf("%d%d%d", &n, &root, &m);for (int i = 1; i < n; i++){int u, v;scanf("%d%d", &u, &v);g[u].push_back(v), g[v].push_back(u);}dfs1(root, root);while (m--){int u;scanf("%d", &u);printf("%lld\n", ans[u] % mod);}
}int main()
{solve();return 0;
}

双倍经验


http://www.ppmy.cn/news/712767.html

相关文章

HDU 5002 Tree

题意&#xff1a; 一棵树 支持删边加边、路径权值加值、路径权值改值、路径求第二大的数字和其个数 思路&#xff1a; LCT的第二题 题意已经把功能都告诉了 比较裸 要注意的是权值加值和改值两个操作的标记下放问题 要先down改值 再down加值 对于路径的操作通过mroot…

例5002 进制转换

例5002 进制转换 Time Limit: 1000/1000MS (C/Others) Memory Limit: 65536/65536KB (C/Others) Total Submissions: 190 Accepted Submissions: 39 Problem Description 输入一个十进制数N&#xff0c;将它转换成R进制数输出。 Input 输入数据包含多个测试实例&#xff0c;每…

LCT - hdu5002 Tree

题目&#xff1a; http://acm.hdu.edu.cn/showproblem.php?pid5002 题意&#xff1a; 给一棵树树&#xff0c;提供四种操作 1&#xff1a;删除(x,y)边&#xff0c;添加(a,b)边&#xff0c;保证操作前后都是合法的树 2&#xff1a;修改a--b路径上所有点的权值为x 3&#…

1144: 5002 进制转换

题目描述 输入一个十进制数N&#xff0c;将它转换成R进制数输出。 输入 输入数据包含多个测试实例&#xff0c;每个测试实例包含两个整数N&#xff08;32位整数&#xff09;和R&#xff08;2<R<16&#xff0c;R ! 10&#xff09;。 输出 为每个测试实例输出转换后的…

hdu5002:Tree (LCT)

题目传送门&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid5002 题目大意&#xff1a;一开始给你一棵有N个点的树&#xff08;N<10^5&#xff09;&#xff0c;每个点有权值。现在有四种操作&#xff1a;1&#xff1a;x y a b删掉连接x,y的边&#xff0c;并连接a,b…

P5002 专心OI - 找祖先【题解】

题目链接&#xff1a;P5002 专心OI - 找祖先。 这是一道既和 LCA 有关&#xff0c;又可以称得上和 LCA 没有多少关系的题。 这道题中的数据范围告诉我们&#xff0c;存图要用邻接表&#xff08;矩阵表示很悲伤&#xff09;&#xff0c;所以先把它的代码给码上&#xff1a; /…

InetAddress.getLocalHost().getHostName() took 5002 milliseconds to respond.

1.使用工具 MAC idea mysql 2.错误场景 在启动项目的时候报错&#xff1a; InetAddress.getLocalHost().getHostName() took 5002 milliseconds to respond.3.解决方案 获取本机的主机名称&#xff08;mac电脑&#xff09; 可以使用 hostname命令 hostname 就可以拿到 **…

ias 配置服务器 文件属性,WX5002与Windows IAS配合实现同一SSID不同VLAN功能(即动态mac-vlan功能)的典型配置...

WX5002与Windows IAS配合实现同一SSID不同VLAN功能(即动态mac-vlan功能)的典型配置 适用WX5002版本:Comware Software, Version 5.20, Release 1106P02 一、组网需求 WX5002、WA2110、H3C POE交换机、便携机(安装有11b/g无线网卡)、Windows IAS服务器 二、组网图 WX5002的IP地…