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. Docker 的安装及常用命令

    CentOS Docker 安装 参看链接 Windows安装 Docker Desktop 官方下载地址: https://hub.docker.com/editions/community/doc ...

  2. shell学习总结

    shell教程 第一个shell脚本 打开文本编辑器(可以使用 vi/vim 命令来创建文件), 新建一个文件 test.sh,扩展名为 sh(sh代表shell) #!/bin/bash echo ...

  3. JumpServer安装及应用

    jumpserver安装 安装所需软件包 [root@localhost ~]# yum -y update [root@localhost ~]# dnf install -y wget curl ...

  4. 曲线艺术编程 coding curves 第八章 贝赛尔曲线(Bézier Curves)

    贝赛尔曲线(Bézier Curves) 原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(s ...

  5. 时隔多年,从新认识浮动float

    开场白 随着css的发展,在加上各种优秀ui库的兴起. 我们在项目中浮动用的很少. 但并不意味着我们不使用浮动了. 曾几何时,浮动这个属性是那个遥远时代的'超级明星' 排版,布局,都需要使用他. 今不 ...

  6. 【了解LLM】——LoRA

    本文地址:https://www.cnblogs.com/wanger-sjtu/p/17470327.html 论文链接:link code: github 什么是LoRA LoRA,英文全称Low ...

  7. CoFiltering:BestPracticesandTechniquesinTextGeneration

    目录 Co-Filtering: Best Practices and Techniques in Text Generation Introduction: Text generation has ...

  8. React后台管理系统08 左侧菜单栏点击事件以及设置只有一个菜单展开项

    我们在Menu组件身上添加一个点击事件:对应的函数写一个回调函数:获取当前对象的e的身上的key, 这里其实不难看出e就是当前点击时的menu对象,我们这里获取的是e的key,对应上面定义的属性. 此 ...

  9. Java求数组元素的最大值和最小值

    代码如下: public static void main(String[] args) { int [] a = {1,2,3,88,2,90}; int max = a[0]; int min = ...

  10. Istio 入门(三):体验 Istio、微服务部署、可观测性

    本教程已加入 Istio 系列:https://istio.whuanle.cn 目录 3,快速入门 书店微服务 预先准备 details 应用 ratings 应用 reviews v1/v2/v3 ...