\(\mathcal{Description}\)

  Link.

  给定一棵 \(n\) 个点的树和 \(q\) 次加边操作。求出每次操作后,满足 \(u,v,w\) 互不相等,路径 \((u,w)\) 与 \((v,w)\) 无重复边的有序三元组 \((u,v,w)\) 的个数。

  \(n,q\le10^5\)。

\(\mathcal{Solution}\)

  考虑原树上,以某个点为 \(w\) 的贡献。记 \(\operatorname{contr}(u)\) 为 \(u\) 的贡献,则有:

\[\operatorname{contr}(u)=(n-1)(n-1)-\sum_{v\in son_u}siz_v^2-(n-siz_u)(n-siz_u)
\]

  又发现一个边双中的每个点都应是等价的。所以对于以 \(u\) 为顶点的边双,维护 \(val_u=\sum_{v\in son_u}siz_v^2\) 和大小 \(s_u\),我们也能求出它的贡献:

\[\operatorname{contr}(u)=s_u((n-s_u)^2-val_u-(n-siz_u)^2)+2s_u(s_u-1)(n-s_u)+s_u(s_u-1)(s_u-2)
\]

  加边时,暴力爬树,并用并查集维护连通边双即可。

  复杂度 \(\mathcal O(n\log n)\)(并查集不带启发式合并)。

\(\mathcal{Code}\)

#include <cstdio>
#include <assert.h> typedef long long LL; const int MAXN = 1e5;
int n, ecnt, head[MAXN + 5];
int fa[MAXN + 5], dep[MAXN + 5], siz[MAXN + 5], blk[MAXN + 5];
LL ans, val[MAXN + 5]; struct Edge { int to, nxt; } graph[MAXN * 2 + 5]; inline void link ( const int s, const int t ) {
graph[++ ecnt] = { t, head[s] };
head[s] = ecnt;
} inline char fgc () {
static char buf[1 << 17], *p = buf, *q = buf;
return p == q && ( q = buf + fread ( p = buf, 1, 1 << 17, stdin ), p == q ) ? EOF : *p ++;
} inline int rint () {
int x = 0; char d = fgc ();
for ( ; d < '0' || '9' < d; d = fgc () );
for ( ; '0' <= d && d <= '9'; d = fgc () ) x = x * 10 + ( d ^ '0' );
return x;
} inline void wint ( const LL x ) {
if ( 9 < x ) wint ( x / 10 );
putchar ( x % 10 ^ '0' );
} struct DSU {
int fa[MAXN + 5];
inline void init () { for ( int i = 1; i <= n; ++ i ) fa[i] = i; }
inline int find ( const int x ) { return x ^ fa[x] ? fa[x] = find ( fa[x] ) : x; }
inline bool unite ( int x, int y ) {
x = find ( x ), y = find ( y );
return x ^ y ? fa[x] = y, true : false;
}
} dsu; inline void init ( const int u ) {
siz[u] = blk[u] = 1;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa[u] ) {
dep[v] = dep[fa[v] = u] + 1, init ( v );
siz[u] += siz[v];
val[u] += 1ll * siz[v] * siz[v];
}
}
} inline void calc ( const int u, const int k ) {
assert ( u == dsu.fa[u] );
int s = blk[u];
ans += 1ll * k * s * ( 1ll * ( n - s ) * ( n - s ) - val[u] - 1ll * ( n - siz[u] ) * ( n - siz[u] ) );
ans += 2ll * k * s * ( s - 1 ) * ( n - s );
ans += 1ll * k * s * ( s - 1 ) * ( s - 2 );
} inline void merge ( const int u, const int v ) {
assert ( u == dsu.fa[u] && v == dsu.fa[v] && dep[u] < dep[v] );
calc ( u, -1 ), calc ( v, -1 );
val[u] -= 1ll * siz[v] * siz[v], val[u] += val[v], blk[u] += blk[v];
calc ( u, 1 ), dsu.unite ( v, u );
} int main () {
n = rint (), dsu.init ();
for ( int i = 1, u, v; i < n; ++ i ) {
u = rint (), v = rint ();
link ( u, v ), link ( v, u );
}
init ( 1 );
for ( int i = 1; i <= n; ++ i ) calc ( i, 1 );
wint ( ans ), putchar ( '\n' );
for ( int q = rint (), u, v; q --; ) {
u = rint (), v = rint ();
while ( dsu.find ( u ) ^ dsu.find ( v ) ) {
if ( dep[dsu.find ( u )] < dep[dsu.find ( v )] ) u ^= v ^= u ^= v;
u = dsu.find ( u );
merge ( dsu.find ( fa[u] ), u );
}
wint ( ans ), putchar ( '\n' );
}
return 0;
}

Solution -「CF 855G」Harry Vs Voldemort的更多相关文章

  1. Solution -「CF 1342E」Placing Rooks

    \(\mathcal{Description}\)   Link.   在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...

  2. Solution -「CF 1622F」Quadratic Set

    \(\mathscr{Description}\)   Link.   求 \(S\subseteq\{1,2,\dots,n\}\),使得 \(\prod_{i\in S}i\) 是完全平方数,并最 ...

  3. Solution -「CF 923F」Public Service

    \(\mathscr{Description}\)   Link.   给定两棵含 \(n\) 个结点的树 \(T_1=(V_1,E_1),T_2=(V_2,E_2)\),求一个双射 \(\varph ...

  4. Solution -「CF 923E」Perpetual Subtraction

    \(\mathcal{Description}\)   Link.   有一个整数 \(x\in[0,n]\),初始时以 \(p_i\) 的概率取值 \(i\).进行 \(m\) 轮变换,每次均匀随机 ...

  5. Solution -「CF 1586F」Defender of Childhood Dreams

    \(\mathcal{Description}\)   Link.   定义有向图 \(G=(V,E)\),\(|V|=n\),\(\lang u,v\rang \in E \Leftrightarr ...

  6. Solution -「CF 1237E」Balanced Binary Search Trees

    \(\mathcal{Description}\)   Link.   定义棵点权为 \(1\sim n\) 的二叉搜索树 \(T\) 是 好树,当且仅当: 除去最深的所有叶子后,\(T\) 是满的: ...

  7. Solution -「CF 623E」Transforming Sequence

    题目 题意简述   link.   有一个 \(n\) 个元素的集合,你需要进行 \(m\) 次操作.每次操作选择集合的一个非空子集,要求该集合不是已选集合的并的子集.求操作的方案数,对 \(10^9 ...

  8. Solution -「CF 1023F」Mobile Phone Network

    \(\mathcal{Description}\)   Link.   有一个 \(n\) 个结点的图,并给定 \(m_1\) 条无向带权黑边,\(m_2\) 条无向无权白边.你需要为每条白边指定边权 ...

  9. Solution -「CF 599E」Sandy and Nuts

    \(\mathcal{Description}\)   Link.   指定一棵大小为 \(n\),以 \(1\) 为根的有根树的 \(m\) 对邻接关系与 \(q\) 组 \(\text{LCA}\ ...

随机推荐

  1. vscode 前端好用插件汇总

    本篇文章根据实际开发中使用的扩展插件,结合<精选!15 个必备的 VSCode 插件(前端类)>.<vscode 插件推荐 - 献给所有前端工程师(2017.8.18更新)>中 ...

  2. console.log(a)和console.log(window.a)的区别?

    console.log(window.l); //undefined console.log(l); //Uncaught ReferenceError: l is not defined js对于未 ...

  3. 关于APP设计规范和一些图层命名

    首先,本人大学计算机专业出身,学过编程,工作的时候做过 产品经理,设计师,前端工程师,对工作的流程都有一些见解. 现在主攻前端工程师,做Web APP.今天收到设计师的设计稿,一看图层分类,这让我感觉 ...

  4. h5跳转高德地图

    <a href="https://uri.amap.com/marker?position=经度,纬度&name=所在的位置名称">高德地图</a>

  5. Android学习笔记4

    activity配置文件 //AndroidMainifest.xml <?xml version="1.0" encoding="utf-8"?> ...

  6. 观察者模式(Observer模式)

    模式的定义与特点 观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.这种模式有时又称作发布-订阅模式.模型- ...

  7. Rsync安装配置

    一.先准备两台CentOS服务器,假定是 1.172.18.2.225(服务端) 需要配置rsyncd.conf文件 2.172.18.2.227(客户端) 不需要配置rsyncd.conf文件 二. ...

  8. 在EntityFrameworkCore中记录EF修改日志,保存,修改字段的原始值,当前值,表名等信息

    突发奇想,想把业务修改的所有字段原始值和修改后的值,做一个记录,然后发现使用EF可以非常简单的实现这个功能 覆盖父类中的 SaveShanges() 方法 public new int SaveCha ...

  9. python 小兵(6)函数根据问题详解

    _list = []for i in range(3): def func(a): return i+a_list.append(func)for f in _list: print(f(1)) 首先 ...

  10. Codeforces Round #738 (Div. 2)

    Codeforces Round #738 (Div. 2) 跳转链接 A. Mocha and Math 题目大意 有一个长度为\(n\)的数组 可以进行无数次下面的操作,问操作后数组中的最大值的最 ...