题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=1969

题解

如果我们把整个图边双联通地缩点,那么最终会形成一棵树的样子。

那么在这棵树上,\(x\) 和 \(y\) 两个点的答案就是它们之间的不在环中的边的数量。

现在考虑动态维护每一条边在不在环中。发现动态删除的话不太好做,所以时光反转,改成插入一条边。

先随便建立一棵生成树,然后如果插入一条非树边,那么两个端点之间的边就都是在环中的边了。

用树剖维护就可以了。


时间复杂度 \(O(q\log^2 n)\)。

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I>
inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} #define lc o << 1
#define rc o << 1 | 1 const int N = 30000 + 7;
const int M = 100000 + 7;
const int QQ = 40000 + 7; int n, m, Q, dfc;
int dep[N], f[N], siz[N], son[N], dfn[N], top[N], pre[N];
int ans[QQ];
std::set<pii> ss; struct Query {int opt, x, y; } qq[QQ]; struct Edge { int to, ne; } g[M << 1]; int head[N], tot;
inline void addedge(int x, int y) { g[++tot].to = y, g[tot].ne = head[x], head[x] = tot; }
inline void adde(int x, int y) { addedge(x, y), addedge(y, x); } inline void dfs1(int x, int fa = 0) {
dep[x] = dep[fa] + 1, f[x] = fa, siz[x] = 1;
for fec(i, x, y) if (y != fa && !dep[y] && !ss.count(pii(x, y))) dfs1(y, x), siz[x] += siz[y], siz[y] > siz[son[x]] && (son[x] = y);
}
inline void dfs2(int x, int pa) {
dfn[x] = ++dfc, top[x] = pa, pre[dfc] = x;
if (!son[x]) return; dfs2(son[x], pa);
for fec(i, x, y) if (y != f[x] && y != son[x] && !dfn[y] && !ss.count(pii(x, y))) dfs2(y, y);
} struct Node { int sum, set; } t[N << 2];
inline void build(int o, int L, int R) {
t[o].set = 0;
if (L == R) return t[o].sum = 1, (void)0;
int M = (L + R) >> 1;
build(lc, L, M), build(rc, M + 1, R);
t[o].sum = t[lc].sum + t[rc].sum;
}
inline void qset(int o, int L, int R, int l, int r) {
if (l > r) return;
if (t[o].set) return;
if (l <= L && R <= r) return t[o].sum = 0, t[o].set = 1, (void)0;
int M = (L + R) >> 1;
if (l <= M) qset(lc, L, M, l, r);
if (r > M) qset(rc, M + 1, R, l, r);
t[o].sum = t[lc].sum + t[rc].sum;
}
inline int qsum(int o, int L, int R, int l, int r) {
if (l > r) return 0;
if (t[o].set) return 0;
if (l <= L && R <= r) return t[o].sum;
int M = (L + R) >> 1;
if (r <= M) return qsum(lc, L, M, l, r);
if (l > M) return qsum(rc, M + 1, R, l, r);
return qsum(lc, L, M, l, r) + qsum(rc, M + 1, R, l, r);
} inline void upd(int x, int y) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) std::swap(x, y);
qset(1, 1, n, dfn[top[x]], dfn[x]);
x = f[top[x]];
}
if (dep[x] > dep[y]) std::swap(x, y);
qset(1, 1, n, dfn[son[x]], dfn[y]);
}
inline int qry(int x, int y) {
int ans = 0;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) std::swap(x, y);
ans += qsum(1, 1, n, dfn[top[x]], dfn[x]);
x = f[top[x]];
}
if (dep[x] > dep[y]) std::swap(x, y);
return ans += x != y ? qsum(1, 1, n, dfn[son[x]], dfn[y]) : 0;
} inline void work() {
dfs1(1), dfs2(1, 1), build(1, 1, n);
for (int x = 1; x <= n; ++x) for fec(i, x, y)
if (x < y && f[x] != y && f[y] != x && !ss.count(pii(x, y))) upd(x, y);
while (Q) {
int opt = qq[Q].opt, x = qq[Q].x, y = qq[Q].y;
--Q;
if (opt == 0) upd(x, y);
else ans[++ans[0]] = qry(x, y);
}
while (ans[0]) printf("%d\n", ans[ans[0]--]);
} inline void init() {
read(n), read(m);
int opt, x, y;
for (int i = 1; i <= m; ++i) read(x), read(y), adde(x, y);
while (read(opt), ~opt) {
read(x), read(y);
if (opt == 0) ss.insert(pii(x, y)), ss.insert(pii(y, x));
qq[++Q] = (Query){ opt, x, y };
}
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj1969 [Ahoi2005]LANE 航线规划 树链剖分的更多相关文章

  1. BZOJ 1969: [Ahoi2005]LANE 航线规划( 树链剖分 )

    首先我们要时光倒流, 倒着做, 变成加边操作维护关键边. 先随意搞出一颗树, 树上每条边都是关键边(因为是树, 去掉就不连通了)....然后加边(u, v)时, 路径(u, v)上的所有边都变成非关键 ...

  2. 【bzoj1959】[Ahoi2005]LANE 航线规划 树链剖分+线段树

    题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...

  3. BZOJ 1969: [Ahoi2005]LANE 航线规划 [树链剖分 时间倒流]

    题意: 一张图,删除边,求两点之间的割边数量.保证任意时刻图连通 任求一棵生成树,只有树边可能是割边 时间倒流,加入一条边,就是两点路径上的边都不可能是割边,区间覆盖... 然后本题需要把边哈希一下, ...

  4. bzoj1969: [Ahoi2005]LANE 航线规划(树链剖分)

    只有删边,想到时间倒流. 倒着加边,因为保证图连通,所以一开始一定至少是一棵树.我们先建一棵树出来,对于每一条非树边,两个端点在树上这段路径的边就不会变成关键边了,所以将它们对答案的贡献删去,那么直接 ...

  5. [bzoj1969] [Ahoi2005]LANE 航线规划

    tarjan.并查集.树状数组.树链剖分. 时间倒流,变删边为加边. 先求一波边双联通分量,缩点. 题目保证最后还是整张图联通的..所以就是一棵树. 现在的操作就是,将路径上的边权置0(加边时),查询 ...

  6. 洛谷 P2542 [AHOI2005]航线规划 树链剖分_线段树_时光倒流_离线

    Code: #include <map> #include <cstdio> #include <algorithm> #include <cstring&g ...

  7. BZOJ1969: [Ahoi2005]LANE 航线规划(LCT)

    Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 587  Solved: 259[Submit][Status][Discuss] Description ...

  8. luogu2542 航线规划 (树链剖分)

    不会lct,所以只能树剖乱搞 一般这种删边的题都是离线倒着做,变成加边 他要求的结果其实就是缩点以后两点间的距离. 然后先根据最后剩下的边随便做出一个生成树,然后假装把剩下的边当成加边操作以后处理 这 ...

  9. 【BZOJ1969】[Ahoi2005]LANE 航线规划 离线+树链剖分+线段树

    [BZOJ1969][Ahoi2005]LANE 航线规划 Description 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由 ...

随机推荐

  1. JavaSE知识点:finalize,treeMap

    *)finalize finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等. *)treeMap 参考 ...

  2. HTML5和CSS3兼容清单

    1.CSS3 2.CSS3选择器 3.HTML5 4.HTML5 From  

  3. React-Native 之 GD (十八)监听 TabBarItem 点击与传值实现 点击 Item 进行刷新功能

    监听 TabBarItem 点击与传值实现 点击 Item 进行刷新功能 原版 APP 中当我们点击 首页和海淘 2个 Item 时,会马上获取最新数据个数然后进行更新,这边来实现一下这个功能. 1. ...

  4. fedora安装ep,forge,fusion等第三方软件库

    fedora安装ep,forge,fusion等第三方软件库 官方的发行版 抛弃了有 版权争议的 软件, 特别是 包括很多第三方的 多媒体软件, 如播放 mp3, flv等的软件 解码器 这就要靠 使 ...

  5. Python selenium 三种等待方式详解(必会)

    很多人在群里问,这个下拉框定位不到.那个弹出框定位不到…各种定位不到,其实大多数情况下就是两种问题:1 有frame,2 没有加等待.殊不知,你的代码运行速度是什么量级的,而浏览器加载渲染速度又是什么 ...

  6. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_2_一切皆为字节

    这里的视频就是字节的形式,为了看着方便转换成了MB.一个字节就是8个二进制 包括文本,都是以字节的形式存储的

  7. rpm安装软件时提示warning: *.rpm: Header V3 RSA/SHA256 Signature, keykey ID c105b9de

    在RedHat下有时候用rpm安装软件是会出现下面则中错误 1.安装时提示:warning: *.rpm: Header V3 RSA/SHA256 Signature, keykey ID c105 ...

  8. python 操作openpyxl导出Excel 设置单元格格式以及合并处理

    贴上一个例子,里面设计很多用法,根据将相同日期的某些行合并处理. from openpyxl import Workbook from openpyxl.styles import Font, Fil ...

  9. Python uuid库中 几个uuid的区别

    在用到uuid库的时候,发现uuid有很多个,比较好奇,就查了一下他们的区别 uuid1()——基于时间戳 uuid2()——基于分布式计算环境DCE(Python中没有这个函数) uuid3()—— ...

  10. 06 使用bbed修复delete的数据--01

    06 使用bbed修复delete的数据--01 根据rowid查看数据文件和block号 SYS@ orcl ; ROWID ID NAME FILE# BLOCK# --------------- ...