link。

还算萌,但是代码有些难写……

你首先会想要

int n, m, fa[20][300100], pa[300100], dep[300100], cnt[900100];
int ldf[300100], rdf[300100], dfc, qwq;
vi<int> G[300100];
struct path {
int x, y, sx, sy, lca;
};
void dfs(int x, int pre) {
fa[0][x] = pa[x] = pre;
dep[x] = dep[pre]+1;
ldf[x] = ++dfc;
for (int i=1; i<20; ++i) {
fa[i][x] = fa[i-1][fa[i-1][x]];
}
for (auto y : G[x]) {
if (y != pre) {
dfs(y, x);
}
}
rdf[x] = dfc;
}
int lca(int x, int y) {
if (dep[x] < dep[y]) {
swap(x, y);
}
for (int i=19; i>=0; --i) {
if (dep[fa[i][x]] >= dep[y]) {
x = fa[i][x];
}
}
if (x == y) {
return x;
}
for (int i=19; i>=0; --i) {
if (fa[i][x] != fa[i][y]) {
x = fa[i][x], y = fa[i][y];
}
}
return pa[x];
}
int jump(int x, int d) {
if (d < 0) {
return n+(++qwq);
}
for (int i=19; i>=0; --i) {
if ((d>>i)&1) {
x = fa[i][x];
}
}
return x;
}
int bit[300100];
void add(int x, int y) {
for (; x<=n; x+=x&-x) {
bit[x] += y;
}
}
int qry(int x) {
int res = 0;
for (; x; x-=x&-x) {
res += bit[x];
}
return res;
}
int qry(int l, int r) {
return qry(r)-qry(l-1);
}
void executer() {
cin >> n;
for (int i=1,x,y; i<n; ++i) {
cin >> x >> y;
G[x].push_back(y);
G[y].push_back(x);
}
dfs(1, 0);
cin >> m;
vi<path> paths(m);
for (auto& it : paths) {
cin >> it.x >> it.y;
it.lca = lca(it.x, it.y);
it.sx = jump(it.x, dep[it.x]-dep[it.lca]-1);
it.sy = jump(it.y, dep[it.y]-dep[it.lca]-1);
if (it.sx > it.sy) {
swap(it.sx, it.sy), swap(it.x, it.y);
}
}
sort(paths.begin(), paths.end(), [&](const path& lhs, const path& rhs) {
return dep[lhs.lca] < dep[rhs.lca]
|| (dep[lhs.lca] == dep[rhs.lca] && lhs.lca < rhs.lca)
|| (lhs.lca == rhs.lca && lhs.sx > rhs.sx)
|| (lhs.sx == rhs.sx && lhs.sy > rhs.sy);
});
LL ans = 0;
for (int i=0; i<m;) {
int j = i;
while (j < m-1 && paths[j+1].lca == paths[j].lca) {
j++;
}
LL now = 0;
for (int l=i; l<=j;) {
int r = l;
while (r < j && paths[r+1].sx == paths[r].sx) {
r++;
}
for (int k=l; k<=r; ++k) {
ans += now-cnt[paths[k].sy];
}
for (int k=l; k<=r; ++k) {
cnt[paths[k].sx]++, cnt[paths[k].sy]++;
}
now += r-l+1, l = r+1;
}
for (int k=i; k<=j; ++k) {
cnt[paths[k].sx] = cnt[paths[k].sy] = 0;
}
for (int k=i; k<=j; ++k) {
ans += qry(ldf[paths[k].lca], rdf[paths[k].lca]);
if (paths[k].sx <= n) {
ans -= qry(ldf[paths[k].sx], rdf[paths[k].sx]);
}
if (paths[k].sy <= n) {
ans -= qry(ldf[paths[k].sy], rdf[paths[k].sy]);
}
}
for (int k=i; k<=j; ++k) {
add(ldf[paths[k].x], 1), add(ldf[paths[k].y], 1);
}
i = j+1;
}
cout << ans << "\n";
}

「codeforces - 1486F」Pairs of Paths的更多相关文章

  1. Solution -「CF 1391E」Pairs of Pairs

    \(\mathcal{Description}\)   Link.   给定一个 \(n\) 个点 \(m\) 条边的无向图,在其上找到一条包括不少于 \(\lceil\frac{n}2\rceil\ ...

  2. 「CodeForces 581D」Three Logos

    BUPT 2017 Summer Training (for 16) #3A 题意 给你三个矩形,需要不重叠不留空地组成一个正方形.不存在输出-1,否则输出边长和这个正方形(A,B,C表示三个不同矩形 ...

  3. 「CodeForces - 50C 」Happy Farm 5 (几何)

    BUPT 2017 summer training (16) #2B 题意 有一些二维直角坐标系上的整数坐标的点,找出严格包含这些点的只能八个方向走出来步数最少的路径,输出最少步数. 题解 这题要求严 ...

  4. 「CodeForces - 598B」Queries on a String

    BUPT 2017 summer training (for 16) #1I 题意 字符串s(1 ≤ |s| ≤ 10 000),有m(1 ≤ m ≤ 300)次操作,每次给l,r,k,代表将r位置插 ...

  5. 「CodeForces - 717E」Paint it really, really dark gray (dfs)

    BUPT 2017 summer training (for 16) #1H 题意 每个节点是黑色or白色,经过一个节点就会改变它的颜色,一开始在1节点.求一条路径使得所有点变成黑色. 题解 dfs时 ...

  6. 「CodeForces 476A」Dreamoon and Stairs

    Dreamoon and Stairs 题意翻译 题面 DM小朋友想要上一个有 \(n\) 级台阶的楼梯.他每一步可以上 \(1\) 或 \(2\) 级台阶.假设他走上这个台阶一共用了 \(x\) 步 ...

  7. 「CodeForces 546B」Soldier and Badges 解题报告

    CF546B Soldier and Badges 题意翻译 给 n 个数,每次操作可以将一个数 +1,要使这 n 个数都不相同, 求最少要加多少? \(1 \le n \le 3000\) 感谢@凉 ...

  8. 「Codeforces 79D」Password

    Description 有一个 01 序列 \(a_1,a_2,\cdots,a_n\),初始时全为 \(0\). 给定 \(m\) 个长度,分别为 \(l_1\sim l_m\). 每次可以选择一个 ...

  9. 「Codeforces 468C」Hack it!

    Description 定义 \(f(x)\) 表示 \(x\) 的各个数位之和.现在要求 \(\sum_{i=l}^rf(i)\bmod a\). 显然 ans=solve(l,r)%a; if(a ...

  10. 「Codeforces 724F」Uniformly Branched Trees

    题目大意 如果两棵树可以通过重标号后变为完全相同,那么它们就是同构的. 将中间节点定义为度数大于 \(1\) 的节点.计算由 \(n\) 个节点,其中所有的中间节点度数都为 \(d\) 的互不同构的树 ...

随机推荐

  1. 暑期实习开始啦「GitHub 热点速览」

    无巧不成书,刚好最近有小伙伴在找实习,而 GitHub 热榜又有收录实习信息的项目在榜.所以,无意外本周特推就收录了这个实习项目,当然还有国内版本.除了应景的实习 repo 之外,还有帮你管理文件的 ...

  2. 一定要看的前端codeReview规范指南

    一.前言 针对目录结构.CSS规范.JavaScript规范.Vue规范 可参照官方给出的 风格指南 这里主要总结业务开发中常遇到的代码问题和实践,帮助大家后续各自做好codeReview,一些你遇到 ...

  3. 判断两个矩形是否相交(Rect Intersection)

    0x00 Preface 最近在开发一个2D组态图形组件的过程中,里面的数学模块,涉及到两个矩形是否相交的判断. 这个问题很多年前就写过,算是个小的算法吧. 网络上搜索一下,有很多思路,有一些思路要基 ...

  4. 7.1 套接字(socket)

    套接字(socket)是计算机之间进行通信的一种技术,它允许不同主机上的进程之间进行数据交换.在Python中,我们可以使用socket模块来创建和使用套接字. 首先,我们需要导入socket模块: ...

  5. docker镜像的原理

    docker镜像的原理 docker镜像是由特殊的文件系统叠加而成 最低端是bootfs,并使用宿主机的bootfs 第二层是root文件系统rootfs,称之为base image 再往上是可叠加的 ...

  6. RabbitMQ快速使用代码手册

    本篇博客的内容为RabbitMQ在开发过程中的快速上手使用,侧重于代码部分,几乎没有相关概念的介绍,相关概念请参考以下csdn博客,两篇都是我找的精华帖,供大家学习.本篇博客也持续更新~~~ 内容代码 ...

  7. Taurus .Net Core 微服务开源框架:Admin 插件【3】 - 指标统计管理

    前言: 继上篇:Taurus .Net Core 微服务开源框架:Admin 插件[2] - 系统环境信息管理 本篇继续介绍下一个内容: 1.系统指标节点:Metric - API 界面 界面图如下: ...

  8. 【笔试实战】LeetCode题单刷题-编程基础 0 到 1【三】

    682. 棒球比赛 题目链接 682. 棒球比赛 题目描述 你现在是一场采用特殊赛制棒球比赛的记录员.这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分. 比赛开始时,记录是空白的.你 ...

  9. 走近高德驾车ETA(预估到达时间)

    1. 什么是驾车ETA 临近节假,长途自驾返乡的你是否曾为无法预知路上到底有多堵而纠结?通勤上班,作为有车一族的你是否在为路况变幻莫测的早晚高峰而烦恼?外出旅行,赶火车.赶飞机的你是否还在为担心错过班 ...

  10. 即构SDK新增焦点语音功能,可实现特定用户语音的聚焦

    2021年,即构SDK每月迭代如期而至.今年,我们会着重介绍每月SDK的重要新增功能,让大家更清晰的了解到这些新功能的特性及应用场景. 重点新增功能 多人语音通话场景下的焦点语音功能 功能介绍 即构S ...