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. 逍遥自在学C语言 | for循环详解

    前言 C语言中的循环结构时,for循环是最常用的一种.它允许重复执行一段代码,直到满足特定条件为止. 本文将详细介绍for循环的用法,并提供相关的可编译运行的C代码示例. 一.人物简介 第一位闪亮登场 ...

  2. 2022 i春秋冬季赛

    Misc nan's analysis 下载附件之后,打开是一道流量数据包. 开始分析流量,首先看到的是FTP流量 追踪tcp,发现ftp账号密码 先记录一下,接下来发现一个zip文件,选择原始数据, ...

  3. JavaScript 显示数据

    JavaScript 显示数据 JavaScript 可以通过不同的方式来输出数据: 使用 window.alert() 弹出警告框. 使用 document.write() 方法将内容写到 HTML ...

  4. ndk std_thread 获取pid

    本文链接 https://www.cnblogs.com/wanger-sjtu/p/16817532.html 最近在解决tvm绑核问题时,发现android下绑核只有sched_setaffini ...

  5. Linux系统运维之subversionEdge部署

    一.介绍 Subversion Edge是Collabnet公司发布的SVN和Apache等组件结合的SVN管理工具.由于安装过subversion+apache,发现添加账户都需要登录服务器改配置, ...

  6. harbor 搭建和部署

    Docker官方的Docker Registry镜像,可以用来储存和分发Docker镜像.不过实在不昨的,仅仅能储存和分发镜像,也不提供UI,你还得自己找一个过时的UI搭建,受限制于Docker Re ...

  7. go select 使用总结

    转载请注明出处: 在Go语言中,select语句用于处理多个通道的并发操作.它类似于switch语句,但是select语句用于通信操作,而不是条件判断.select语句会同时监听多个通道的操作,并选择 ...

  8. Pyinstaller打包 Pytest+Allure成exe文件执行时,报错ERROR: usage: apitest.exe [options] [file_or_dir] [file_or_dir] [...] xxx.exe: error: unrecognized arguments: --alluredir=.\\report\\xml --clean-alluredir

    网上找了很多案例啊  都没解决问题,由本人的多次试验 终于成功解决 1.打包运行 pyinstaller -D  xxx.py 打包成功后  执行exe报错  如下 2.此情况是说明  命令无法正确识 ...

  9. AcWing 4489. 最长子序列题解

    思路 此题较为简单,简述一下思路. 设原始数列为 \(a\). 定义 \(dp\) 数组,初始值都为 \(1\). 遍历数组,如果 \(a[i-1]*2 \leq a[i]\) ,那么 \(dp[i] ...

  10. 数据安全没保证?GaussDB(for Redis)为你保驾护航

    摘要:GaussDB (for Redis)通过账号管理.权限隔离.高危命令禁删/重命名.安全IP免密登录.实例回收站等企业级特性,保障用户数据库数据和信息安全. 本文分享自华为云社区<数据安全 ...