题意

给出一棵n个点,n-1条边的树。现在计算所有标号为x到y的距离之和(满足y>x且y是x的倍数)

思路

关于树上任意两点距离之和,一开始想到树形dp,可树形dp,是对每条边,求所有可能的路径经过此边的次数,是求出边两端的点数,这条边被经过的次数就是两端点数的乘积。
但是该题对计算的距离加了限制(y>x且y是x的倍数),显然不能用树形dp来做了。
接下来想到图论部分的算法,想处理出来两点之间的距离,也就是最短路,但是n=2e5,跑n遍dijkstra或者n遍spfa在复杂度上肯定会T,故不可行。
队友提到LCA(最近公共祖先),随意定义一个根root,用LCA倍增法预处理出来每个点到根的深度数组dep[],然后找两个点的最近公共祖先lca,那么这两点间的距离即 dep[i] + dep[i*j] - dep[lca] * 2 + 1 (根据题意,距离是这两点间边的个数+1)

代码是kuangbin的LCA倍增法板子改了一波。

AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 2e5+5;
const int DEG = 20;
typedef long long ll;struct Edge{int to, next;
}edge[maxn*2];
int tot, head[maxn];void init() {tot = 0;memset(head, -1, sizeof head);
}void addedge(int u, int v) {edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;
}int fa[maxn][20];
int dep[maxn];void BFS(int root) {queue<int> que;dep[root] = 0;fa[root][0] = root;que.push(root);while(!que.empty()) {int tmp = que.front();que.pop();for(int i = 1; i < DEG; i++)fa[tmp][i] = fa[fa[tmp][i-1]][i-1];for(int i = head[tmp]; i !=  -1; i = edge[i].next) {int v = edge[i].to;if(v==fa[tmp][0]) continue;dep[v] = dep[tmp] + 1;fa[v][0] = tmp;que.push(v);}}
}int LCA(int u, int v) {if(dep[u] > dep[v]) swap(u, v);int hu = dep[u], hv = dep[v];int tu = u, tv = v;for(int det = hv-hu, i = 0; det; det >>= 1, i++) {if(det & 1) {tv = fa[tv][i];}}if(tu == tv) {return tu;}for(int i = DEG-1; i >= 0; i--) {if(fa[tu][i] == fa[tv][i]) {continue;}tu = fa[tu][i];tv = fa[tv][i];}return fa[tu][0];
}bool flag[maxn];int main() {int n;int u, v;int root;scanf("%d", &n);init();memset(flag, 0, sizeof flag);for(int i = 0; i < n-1; i++) {scanf("%d%d", &u, &v);addedge(u, v);addedge(v, u);flag[v] = true;}for(int i = 1; i <= n; i++) {if(!flag[i]) {root = i;break;}}BFS(root);ll sum = 0;int lca;for(int i = 1; i <= n; i++) {for(int j = 2; i*j <= n; j++) {lca = LCA(i, i*j);sum += dep[i] + dep[i*j] - dep[lca]*2 + 1;}}printf("%lld\n", sum);return 0;
}

View Code


转载于:https://www.cnblogs.com/JinxiSui/p/9740511.html

The North American Invitational Programming Contest 2016 - Tourists ( LCA )相关推荐

  1. 2021-2022 ACM-ICPC Latin American Regional Programming Contest

    2021-2022 ACM-ICPC Latin American Regional Programming Contest J. Joining Pairs 思路: 本题显然答案为NNN的情况为两条 ...

  2. 2011 Michigan Invitational Programming Contest

    Crossings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463 Description ...

  3. Benelux Algorithm Programming Contest 2016 Preliminary 题解

    A. Block Game B. Chess Tournament C. Completing the Square D. Hamming Ellipses E. Lost In The Woods ...

  4. Nordic Collegiate Programming Contest 2016

    A Artwork 输入: n,m表示原图为n*m个白色方格,输入x1,y1,x2,y2表示将x1,y1,x2,y2涂为黑色. 输出: 对于每个x1,y1,x2,y2输入当前图案白色联通块的数目. 思 ...

  5. UCF Local Programming Contest 2016 计蒜客解(补)题报告

    A - Majestic 10(签到) 题目链接 #include <iostream> using namespace std;int main() {int t,x,y,z;scanf ...

  6. 2021-2022 ACM-ICPC Latin American Regional Programming Contest 题解

    B 先两边贪心,然后中间部分卷积 #pragma GCC optimize("O3")#include<iostream> #include<string.h&g ...

  7. 2016 China Collegiate Programming Contest Final

    2016 China Collegiate Programming Contest Final Table of Contents 2016 China Collegiate Programming ...

  8. 2016, IX Samara Regional Intercollegiate Programming Contest I. Deadline

    2016, IX Samara Regional Intercollegiate Programming Contest I. Deadline 题目看这里 Alex works as a devel ...

  9. 2016-2017 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2016)题解

    2016-2017 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2016) A - Artwork 题目描述: 给定N*M的网格,给出Q次 ...

最新文章

  1. [转]图片自动缩放 js图片缩放
  2. vue中v-for循环如何将变量带入class的属性名中
  3. handlerinterceptoradapter 获取请求参数_SSM框架防止重复请求
  4. 山特UPS电源三种工作模式解析
  5. 从CSRF原理到CMS漏洞利用
  6. 【Qt】QBoxLayout类详解
  7. 【开源程序(C++)】获取bing图片并自动设置为电脑桌面背景
  8. centeros7安装mysql5.6_CentOS7安装MySQL5.6
  9. C#实现的UDP收发请求工具类实例
  10. 去除 Css 表单自动填充黄色背景
  11. 正好股票资讯大盘平衡被打破
  12. 计算机程序设计能力考试 PAT 简介(浙大)
  13. Kotlin学习笔记(二)
  14. 我带你去哪里 VIII
  15. 异步六进制加法计数器
  16. 个人网站搭建,个人网站需要什么软件
  17. Havel–Hakimi算法学习笔记(哈维尔算法)详细【Python】
  18. ​从底层技术分析如何调教你的ChatGPT?
  19. 基于Umi的移动端框架Alita-v2.6.7源码
  20. oracle查询练习2(解析+答案)

热门文章

  1. java打字训练课程设计_Java打字训练课程设计
  2. 了区块链开放平台baas_区块链开放平台 BaaS 系统开发,区块链智能合约撰写服务...
  3. SVD decomposition and polar decomposition
  4. php滑动轮播效果,js实现移动端手指滑动轮播图效果
  5. 计算机应用基础任务化教程试题及答案,计算机应用基础任务化教程windows7office2010试卷(带操作题)及答案.doc...
  6. mysql myisam表加索引_MyISAM和InnoDB的索引实现
  7. cannot be null mysql_mysql5.7 column cannot be null-阿里云开发者社区
  8. mysql的存储过程的参数,MySQL存储过程中的参数
  9. visual foxpro 程序员指南_1024程序员节:盘点小红书今年发生的重要bug
  10. 网站代码有服务器系统限制吗,服务器内存最大大小限制(示例代码)