题目大意:给你一棵树,有$3$个操作:

  1. $Q\;p\;q:$询问$p,q$是否连通
  2. $C\;p\;q:$把$p->q$这条边割断
  3. $U\;x:$恢复第$x$次操作二

题解:可以在割断时把这条边赋值上$1$,恢复时赋成$0$,只需要求$p->q$路径和是否为$0$即可,可以用$dfs$序+树状数组维护

卡点:$LCA$越界

C++ Code:

#include <cstdio>
#include <cctype>
#include <algorithm>
namespace __IO {
namespace R {
int x, ch;
inline int read() {
ch = getchar();
while (isspace(ch)) ch = getchar();
for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x = x * 10 + (ch & 15);
return x;
}
}
}
using __IO::R::read; #define maxn 300010 int head[maxn], cnt;
struct Edge {
int to, nxt;
} e[maxn << 1];
inline void add(int a, int b) {
e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
} int n, m;
#define M 20
int fa[maxn][M], sz[maxn], dep[maxn], dfn[maxn], idx;
void dfs(int u) {
dfn[u] = ++idx;
sz[u] = 1;
for (int i = 1; i < M; i++) fa[u][i] = fa[fa[u][i - 1]][i - 1];
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != *fa[u]) {
*fa[v] = u;
dep[v] = dep[u] + 1;
dfs(v);
sz[u] += sz[v];
}
}
} inline int LCA(int x, int y) {
if (x == y) return x;
if (dep[x] < dep[y]) std::swap(x, y);
for (int i = dep[x] - dep[y]; i; i &= i - 1) x = fa[x][__builtin_ctz(i)];
if (x == y) return x;
for (int i = M - 1; ~i; i--) if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
return *fa[x];
} namespace BIT {
int Tr[maxn], res;
inline void modify(int p, int num) {for (; p <= n; p += p & -p) Tr[p] += num;}
inline int query(int p) {for (res = 0; p; p &= p - 1) res += Tr[p]; return res;}
} inline void modify(int x, int num) {
BIT::modify(dfn[x], num);
BIT::modify(dfn[x] + sz[x], -num);
}
inline void query(int x, int y) {
int res = BIT::query(dfn[x]) + BIT::query(dfn[y]) - BIT::query(dfn[LCA(x, y)]) * 2;
puts(res ? "No" : "Yes");
} int war[maxn], Tim;
int main() {
n = read(), m = read();
for (int i = 1, a, b; i < n; i++) {
a = read(), b = read();
add(a, b);
add(b, a);
}
dfs(1);
while (m --> 0) {
int x, y;
char op = getchar();
while (!isalpha(op)) op = getchar();
switch (op) {
case 'Q':
x = read(), y = read();
query(x, y);
break;
case 'C':
x = read(), y = read();
if (dep[x] < dep[y]) std::swap(x, y);
war[++Tim] = x;
modify(x, 1);
break;
case 'U':
x = read();
modify(war[x], -1);
break;
}
}
return 0;
}

  

最新文章

  1. hibernate笔记--组件映射方法
  2. 【ASP.NET Identity系列教程(二)】运用ASP.NET Identity
  3. markdownpad2使用说明
  4. php把时间格式化
  5. Python遍历路径下所有文件
  6. 在office 2010中插入Mathtype出现ctrl+v不能复制的问题
  7. Linux内核空间-用户空间通信之debugfs
  8. org.w3c.dom.Element 缺少 setTextContent 步骤
  9. nmcli命令大集合
  10. win10 uwp 入门
  11. Lepus搭建企业级数据库全方位监控系统
  12. H5新特性——--第三方绘图工具库 echarts(canvas)---SVG绘图
  13. svn 在show log 时候出现 want to go offline
  14. BigDecimal用法总结
  15. vue 自学笔记(七) 组件细节问题
  16. ros 运行rviz时出现 QXcbConnection: XCB error: 148 错误 解决方法
  17. [Java学习]面向对象-package;内部类;UML图表示六种关系
  18. kafka入门2:java 创建及删除 topic
  19. SpringDataRedis事务 专题
  20. SpringIDE的安装

热门文章

  1. VINS(五)非线性优化与在线标定调整
  2. android学习十二 配置变化
  3. nodejs学习笔记(2)
  4. Linux命令应用大词典-第45章 服务器配置
  5. &lt;cctype&gt;
  6. [JSON].getObj( keyPath )
  7. 本地矩阵(Local Matrix)
  8. [Clr via C#读书笔记]Cp9参数
  9. VT-x VT-d 虚拟化在win10中的问题
  10. HTML5+Bootstrap 学习笔记 1