题意

题目链接

分析

考虑枚举每个点的答案,最后除以 2 即可。

可以与 \(u\) 构成合法点对的点集为所有经过了 \(u\) 的链的并。因为这些链两两有交,所以它们的并集构成了一棵树。

考虑维护经过每个点的链并集的大小。一条链是否出现可以树上差分,并集的具体大小就以 \(dfs\) 序为下标建线段树,然后线段树合并即可。

复杂度 \(O(n\log n)\) 。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define go(u) for(int i = head[u], v = e[i].to; i; i = e[i].lst, v = e[i].to)
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define pb push_back
inline int gi() {
int x = 0,f = 1;
char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar();}
while(isdigit(ch)) { x = (x << 3) + (x << 1) + ch - 48; ch = getchar();}
return x * f;
}
template <typename T> inline bool Max(T &a, T b){return a < b ? a = b, 1 : 0;}
template <typename T> inline bool Min(T &a, T b){return a > b ? a = b, 1 : 0;}
const int N = 1e5 + 7;
LL ans;
int n, m, edc, elc, ndc, tim;
int head[N], fa[N], in[N], out[N], fie[N], Log[N << 1], dep[N];
typedef pair<int, int> pii;
pii mi[N << 1][20];
struct edge {
int lst, to;
edge(){}edge(int lst, int to):lst(lst), to(to){}
}e[N << 1];
void Add(int a, int b) {
e[++edc] = edge(head[a], b), head[a] = edc;
e[++edc] = edge(head[b], a), head[b] = edc;
}
void dfs1(int u) {
in[u] = ++tim;
mi[++elc][0] = make_pair(in[u], u);
fie[u] = elc;
go(u)if(v ^ fa[u]) {
fa[v] = u;
dep[v] = dep[u] + 1;
dfs1(v);
mi[++elc][0] = make_pair(in[u], u);
}
out[u] = tim;
}
int Lca(int l, int r) {
l = fie[l], r = fie[r];
if(l > r) swap(l, r);
int k = Log[r - l + 1];
return min(mi[l][k], mi[r - (1 << k) + 1][k]).second;
}
int rt[N];
vector<int>G[N];
struct node {int l, r, A, B, cnt, s;}t[N * 150];
#define Ls t[o].l
#define Rs t[o].r
void pushup(int o) {
t[o].A = t[Ls].A ? t[Ls].A : t[Rs].A;
t[o].B = t[Rs].B ? t[Rs].B : t[Ls].B;
t[o].s = t[Ls].s + t[Rs].s;
if(t[Ls].B && t[Rs].A) t[o].s -= dep[Lca(t[Ls].B, t[Rs].A)];
}
void modify(int p, int l, int r, int &o, int v) {
if(!o) o = ++ndc;
if(l == r) {
t[o].cnt += v;
if(t[o].cnt) t[o].A = t[o].B = p, t[o].s = dep[p];
else t[o].A = t[o].B = t[o].s = 0;
return;
}int mid = l + r >> 1;
if(in[p] <= mid) modify(p, l, mid, Ls, v);
else modify(p, mid + 1, r, Rs, v);
pushup(o);
}
int merge(int l, int r, int x, int y) {
if(!x || !y) return x + y;
if(l == r) {
t[x].cnt += t[y].cnt;
if(t[x].cnt) t[x].A = t[x].B = max(t[x].A, t[y].A), t[x].s = dep[t[x].A];
else t[x].A = t[x].B = t[x].s = 0;
return x;
}int mid = l + r >> 1;
t[x].l = merge(l, mid, t[x].l, t[y].l);
t[x].r = merge(mid + 1, r, t[x].r, t[y].r);
return pushup(x), x;
}
void dfs2(int u) {
go(u)if(v ^ fa[u]) {
dfs2(v);
rt[u] = merge(1, n, rt[u], rt[v]);
}
for(auto v:G[u]) modify(v, 1, n, rt[u], -2);
if(t[rt[u]].A && t[rt[u]].B)
ans += t[rt[u]].s - dep[fa[Lca(t[rt[u]].A, t[rt[u]].B)]] - 1;
}
int main() {
n = gi(), m = gi();
rep(i, 1, n - 1)
Add(gi(), gi());
dep[1] = 1, dfs1(1);
for(int k = 1; 1 << k <= elc; ++k)
for(int i = 1; i + (1 << k) - 1 <= elc; ++i)
mi[i][k] = min(mi[i][k - 1], mi[i + (1 << k - 1)][k - 1]);
for(int i = 2; i <= elc; ++i)
Log[i] = Log[i >> 1] + 1;
rep(i, 1, m) {
int x = gi(), y = gi(), lca = Lca(x, y);
modify(x, 1, n, rt[x], 1);
modify(y, 1, n, rt[x], 1);
modify(x, 1, n, rt[y], 1);
modify(y, 1, n, rt[y], 1);
if(fa[lca]) G[fa[lca]].pb(x), G[fa[lca]].pb(y);
}
dfs2(1);
printf("%d\n", ndc);
printf("%lld\n", ans / 2);
return 0;
}

[ZJOI2019]语言[树链的并、线段树合并]的更多相关文章

  1. bzoj 4034 [HAOI2015] T2(树链剖分,线段树)

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1536  Solved: 508[Submit][Status] ...

  2. bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 10677  Solved: 4313[Submit ...

  3. poj 3237 Tree(树链剖分,线段树)

    Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 7268   Accepted: 1969 Description ...

  4. bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1272  Solved: 451[Submit][Status ...

  5. bzoj 2243 [SDOI2011]染色(树链剖分,线段树)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4637  Solved: 1726[Submit][Status ...

  6. HDU 4366 Successor(树链剖分+zkw线段树+扫描线)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...

  7. 【BZOJ3531】旅行(树链剖分,线段树)

    [BZOJ3531]旅行(树链剖分,线段树) 题面 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教 ...

  8. 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)

    [BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...

  9. [bzoj4196][Noi2015]软件包管理器_树链剖分_线段树

    软件包管理器 bzoj-4196 Noi-2015 题目大意:Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件 ...

  10. 【洛谷5439】【XR-2】永恒(树链剖分,线段树)

    [洛谷5439][XR-2]永恒(树链剖分,线段树) 题面 洛谷 题解 首先两个点的\(LCP\)就是\(Trie\)树上的\(LCA\)的深度. 考虑一对点的贡献,如果这两个点不具有祖先关系,那么这 ...

随机推荐

  1. 从iOS 11看怎样设计APP图标

    苹果WWDC2017开发者大会已经尘埃落定,除了新产品的发布,iOS 11也正式亮相.新系统中,地图.App Store.时钟.相机.联系人等等原生应用都换了新的图标.此次图标的变化势必也会激发下一个 ...

  2. Apache ab.exe压测工具使用

    Apache的ab命令模拟多线程并发请求,测试服务器负载压力,也可以测试nginx.lighthttp.IIS等其它Web服务器的压力. 1,打开cmd,找到安装apache的目录,cd  目录进去, ...

  3. windows平台下spark-shell配置

    一.下载安装spark,http://spark.apache.org/,选择合适版本后下载到本地,解压,bin目录下spark-shell文件就是spark命令行交互的入口. 二.下载安装windo ...

  4. CodeForces 518A Vitaly and Strings (水题,字符串)

    题意:给定两个相同长度的字符串,让你找出一个字符串,字典序在两都之间. 析:这个题当时WA了好多次,后来才发现是这么水,我们只要把 s 串加上,然后和算数一样,该进位进位,然后再和 t 比较就行. 代 ...

  5. 书籍索引 #C++

    卷 计算机 的文件夹 PATH 列表卷序列号为 00000200 0001:8890F:.│ 21天学通C++.pdf│ C++ Primer Plus 第6版 中文版.pdf│ C++ Templa ...

  6. 机器学习—SVM

    一.原理部分: 依然是图片~ 二.sklearn实现: import pandas as pd import numpy as np import matplotlib.pyplot as plt i ...

  7. [label][git-commands] Several Git Commands

    The process of Git commands Operation 1. git commit -m 'fist post' Windows PowerShellCopyright (C) 2 ...

  8. cocos2dx的addChild接口设计

    addChild的几个重载函数挺容易用错的 主要是因为cocos2dx用来给游戏对象设置标签时,用的是整型而不是字符串 导致标签这个参数很容易和同样是使用整型的代表游戏对象的层级关系的参数混淆.

  9. EBS请求查找运行详细信息

    --查找运行请求时间,参数等(可以是某用户的,某个报表) select c.user_name,       papf.full_name,       b.user_concurrent_progr ...

  10. 个人项目-数组求和(语言:C++)

    prog1详细要求: [第一版本程序Prog1要求:] + 给定一个数组,实现数组元素求和:,具体要求:实现对一维数组(a[100])的所有元素相加运算. + 数据准备:a)数组长度:100:b)数组 ...