\(\mathcal{Description}\)

  Link.

  给定一个 \(n\) 个点 \(m\) 条边的连通无向图,并给出 \(q\) 个点对 \((u,v)\),令 \(u\) 到 \(v\) 的路径所必经的结点权值 \(+1\)。求最终每个结点的权值。

  \(n\le10^5\),\(m,q\le2\times10^5\)。

\(\mathcal{Solution}\)

  看到”必经之点“,应该考虑圆方树。

  对于每个点对,直接在圆方树上作差分。具体地,两个圆点的 tag++,其 LCA 和 LCA 的父亲(如果存在)的 tag--,最后一遍 DFS 求每个圆点的子树 tag 和即可。

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

\(\mathcal{Code}\)

#include <cstdio>

const int MAXN = 1e5, MAXM = 2e5;
int n, m, q, snode;
int dfc, top, dfn[MAXN + 5], low[MAXN + 5], stk[MAXN + 5];
int dep[MAXN * 2 + 5], fa[MAXN * 2 + 5][20], tag[MAXN * 2 + 5], sum[MAXN * 2 + 5]; struct Graph {
int ecnt, head[MAXN * 2 + 5], to[MAXM * 2 + 5], nxt[MAXM * 2 + 5];
inline void link ( const int s, const int t ) {
to[++ ecnt] = t, nxt[ecnt] = head[s];
head[s] = ecnt;
}
inline void add ( const int u, const int v ) {
link ( u, v ), link ( v, u );
}
} src, tre; inline bool chkmin ( int& a, const int b ) { return b < a ? a = b, true : false; } inline void Tarjan ( const int u, const int f ) {
dfn[u] = low[u] = ++ dfc, stk[++ top] = u;
for ( int i = src.head[u], v; i; i = src.nxt[i] ) {
if ( ( v = src.to[i] ) == f ) continue;
if ( ! dfn[v] ) {
Tarjan ( v, u ), chkmin ( low[u], low[v] );
if ( low[v] >= dfn[u] ) {
tre.add ( u, ++ snode );
do tre.add ( snode, stk[top] ); while ( stk[top --] ^ v );
}
} else chkmin ( low[u], dfn[v] );
}
} inline void init ( const int u, const int f ) {
dep[u] = dep[fa[u][0] = f] + 1;
for ( int i = 1; i <= 17; ++ i ) fa[u][i] = fa[fa[u][i - 1]][i - 1];
for ( int i = tre.head[u], v; i; i = tre.nxt[i] ) {
if ( ( v = tre.to[i] ) ^ f ) {
init ( v, u );
}
}
} inline int calcLCA ( int u, int v ) {
if ( dep[u] < dep[v] ) u ^= v ^= u ^= v;
for ( int i = 17; ~ i; -- i ) if ( dep[fa[u][i]] >= dep[v] ) u = fa[u][i];
if ( u == v ) return u;
for ( int i = 17; ~ i; -- i ) if ( fa[u][i] ^ fa[v][i] ) u = fa[u][i], v = fa[v][i];
return fa[u][0];
} inline void calcAns ( const int u, const int f ) {
sum[u] = tag[u];
for ( int i = tre.head[u], v; i; i = tre.nxt[i] ) {
if ( ( v = tre.to[i] ) ^ f ) {
calcAns ( v, u ), sum[u] += sum[v];
}
}
} int main () {
scanf ( "%d %d %d", &n, &m, &q ), snode = n;
for ( int i = 1, u, v; i <= m; ++ i ) {
scanf ( "%d %d", &u, &v );
src.add ( u, v );
}
Tarjan ( 1, 0 ), init ( 1, 0 );
for ( int i = 1, u, v; i <= q; ++ i ) {
scanf ( "%d %d", &u, &v );
++ tag[u], ++ tag[v];
int w = calcLCA ( u, v );
-- tag[w];
if ( fa[w] ) -- tag[fa[w][0]];
}
calcAns ( 1, 0 );
for ( int i = 1; i <= n; ++ i ) printf ( "%d\n", sum[i] );
return 0;
}

Solution -「BZOJ 3331」压力的更多相关文章

  1. Solution -「BZOJ 3812」主旋律

    \(\mathcal{Description}\)   Link.   给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...

  2. Solution -「BZOJ #3786」星系探索

    \(\mathcal{Description}\)   Link.   给定一棵含 \(n\) 个点的有根树,点有点权,支持 \(q\) 次操作: 询问 \(u\) 到根的点权和: 修改 \(u\) ...

  3. Solution -「BZOJ 4316」小C的独立集

    \(\mathcal{Description}\)   Link.   求包含 \(n\) 个结点 \(m\) 条边的仙人掌的最大独立集.   \(n\le5\times10^4\),\(m\le6\ ...

  4. 「BZOJ 4228」Tibbar的后花园

    「BZOJ 4228」Tibbar的后花园 Please contact lydsy2012@163.com! 警告 解题思路 可以证明最终的图中所有点的度数都 \(< 3\) ,且不存在环长是 ...

  5. 「BZOJ 3645」小朋友与二叉树

    「BZOJ 3645」小朋友与二叉树 解题思路 令 \(G(x)\) 为关于可选大小集合的生成函数,即 \[ G(x)=\sum[i\in c ] x^i \] 令 \(F(x)\) 第 \(n\) ...

  6. 「BZOJ 4502」串

    「BZOJ 4502」串 题目描述 兔子们在玩字符串的游戏.首先,它们拿出了一个字符串集合 \(S\),然后它们定义一个字符串为"好"的,当且仅当它可以被分成非空的两段,其中每一段 ...

  7. 「BZOJ 4289」 PA2012 Tax

    「BZOJ 4289」 PA2012 Tax 题目描述 给出一个 \(N\) 个点 \(M\) 条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点 \(1\) 到点 \( ...

  8. 「BZOJ 2534」 L - gap字符串

    「BZOJ 2534」 L - gap字符串 题目描述 有一种形如 \(uv u\) 形式的字符串,其中 \(u\) 是非空字符串,且 \(v\) 的长度正好为 \(L\), 那么称这个字符串为 \( ...

  9. 「BZOJ 2956」模积和

    「BZOJ 2956」模积和 令 \(l=\min(n,m)\).这个 \(i\neq j\) 非常不优雅,所以我们考虑分开计算,即: \[\begin{aligned} &\sum_{i=1 ...

随机推荐

  1. win10 防火墙配置 允许局域网其他设备访问本地工程

    1.进入防护墙并找到高级设置 2.选择属性 3.将入站连接设为允许,有三个别忘了,[域配置文件,专用配置文件,公用配置文件]

  2. Java 递归 常见24道题目 总结

    1.N个台阶的走法递归[这里设为10个台阶] /** * N个台阶的走法递归 * <p> * 有个楼梯,台阶有10个,每次可以跳上1阶 或者 2阶 ,那么台阶的走法一共有多少种 */ @T ...

  3. C语言考题:输入一个字符串,将此字符串中特定的字符删去后, 显示新的字符串,要求用函数来完成删去字符的操作。

    #include <stdio.h> #include <string.h> /*此题只需要删除单个字符,比较简单.相信大家也能做出来的.我这个也是可以实现的.只是加了两个判断 ...

  4. nuxt 相关

    https://github.com/xuqiang521/nuxt-ssr-demo https://www.cnblogs.com/laozhang-is-phi/p/10249248.html ...

  5. vue 图片拖拽和滚轮缩放

    这里注意如果自己的页面有滚动条,一定阻止滚动事件的默认行为,否则缩放图片的时候,页面会跟着滚动@mousewheel.prevent 阻止默认行为 <div ref="imgWrap& ...

  6. POJ 1664 放苹果 (递推思想)

    原题链接:http://poj.org/problem?id=1664 思路:苹果m个,盘子n个.假设 f ( m , n ) 代表 m 个苹果,n个盘子有 f ( m , n ) 种放法. 根据 n ...

  7. Spring学习:简单实现一个依赖注入和循环依赖的解决

    依赖注入 什么是依赖注入 使用一个会创建和查找依赖对象的容器,让它负责供给对象. 当a对象需要b对象时,不再是使用new创建,而是从容器中获取,对象与对象之间是松散耦合的关系,有利于功能复用. 依赖: ...

  8. 【PTA】6-2 读文章(*) (31 分)

    请编写函数,从文件中读出文章,将其输出到屏幕上. 函数原型 void ReadArticle(FILE *f); 说明:参数 f 为文件指针.函数读出 f 所指示文件中的文章,将其输出到屏幕上. 裁判 ...

  9. 【C语言】将文本中汉字读入字符数组输出乱码

    输出中文字符乱码 今天从文件中将中文读入字符数组后输出发现其中文变成了乱码,,令人头大. 解决办法 将文本编码格式改成ANSI即可. 打开记事本->文件->另存为->更改编码格式-& ...

  10. 【刷题-LeetCode】213. House Robber II

    House Robber II You are a professional robber planning to rob houses along a street. Each house has ...