题目大意:有$n(n\leqslant3\times10^4)$个点,每个点有点权,$m(m\leqslant3\times10^5)$个操作,操作分三种:

  1. $bridge\;x\;y:$询问节点$x$与节点$y$是否连通,若不连通则连一条边
  2. $penguins\;x\;y:$把节点$x$点权改为$y$
  3. $excursion\;x\;y:$询问$x->y$路径上点权和

题解:$LCT$直接维护即可

卡点:

C++ Code:

#include <algorithm>
#include <cstdio>
#define maxn 30010
#define lc(rt) son[rt][0]
#define rc(rt) son[rt][1] int son[maxn][2], fa[maxn], tg[maxn];
int w[maxn], S[maxn];
inline bool get(int rt, int tg = 1) { return son[fa[rt]][tg] == rt; }
inline bool is_root(int rt) { return !(get(rt, 0) || get(rt)); }
inline void update(int rt) {
S[rt] = S[lc(rt)] + S[rc(rt)] + w[rt];
}
inline void pushdown(int rt) {
if (tg[rt]) {
tg[rt] ^= 1, tg[lc(rt)] ^= 1, tg[rc(rt)] ^= 1;
std::swap(lc(rt), rc(rt));
}
}
inline void rotate(int x) {
int y = fa[x], z = fa[y], b = get(x);
if (!is_root(y)) son[z][get(y)] = x;
fa[son[y][b] = son[x][!b]] = y, son[x][!b] = y;
fa[y] = x, fa[x] = z;
update(y), update(x);
}
inline void splay(int x) {
static int S[maxn], top;
S[top = 1] = x;
for (int y = x; !is_root(y); S[++top] = y = fa[y]) ;
for (; top; top--) pushdown(S[top]);
for (; !is_root(x); rotate(x)) if (!is_root(fa[x]))
get(x) ^ get(fa[x]) ? rotate(x) : rotate(fa[x]);
update(x);
}
inline void access(int x) { for (int t = 0; x; rc(x) = t, t = x, x = fa[x]) splay(x); }
inline void make_root(int rt) { access(rt), splay(rt), tg[rt] ^= 1; }
inline void link(int x, int y) { make_root(x), fa[x] = y; }
inline void split(int x, int y) { make_root(x), access(y), splay(y); }
inline void cut(int x, int y) { split(x, y), lc(y) = fa[x] = 0; }
inline int findroot(int x) {
access(x), splay(x);
while (lc(x)) x = lc(x), pushdown(x);
splay(x);
return x;
}
inline bool connected(int x, int y) {
split(x, y);
return x == findroot(y);
} int n, m;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", w + i);
S[i] = w[i];
}
scanf("%d", &m);
while (m --> 0) {
char op[15];
int x, y;
scanf("%s%d%d", op, &x, &y);
switch (*op) {
case 'b':
if (connected(x, y)) puts("no");
else {
puts("yes");
link(x, y);
}
break;
case 'p':
make_root(x);
w[x] = y;
update(x);
break;
case 'e':
if (connected(x, y)) {
split(x, y);
printf("%d\n", S[y]);
} else puts("impossible");
}
}
return 0;
}

  

最新文章

  1. SQL基础教程--实现增删查改功能(W3School)
  2. 今天&lt;s:hidden&gt;突然能用了
  3. 【JAVA反射机制】
  4. ASP.NET HTTP模拟提交通用类 GET POST
  5. Win7配置Go环境
  6. Http中Cookie与Set-Cookie头
  7. 51nod1242 斐波那契数列 矩阵快速幂
  8. STL 清除模板容器 clear.h
  9. Hive查询结果批量插入分区
  10. SQL Server 2008作业失败无法确定所有者是否有服务器访问权限
  11. myBatis源码之Configuration
  12. jsom快速入门
  13. OpenCV中的KNN
  14. Linux 安装 jdk8
  15. DS二叉树--叶子数量
  16. Eloquent Attach/Detach/Sync Fires Any Event
  17. PHP 使用 GeoIP 进行不同国家 ip 测试
  18. Dozer 使用小结
  19. hibernate 注释 唯一键约束 uniqueConstraints
  20. 发布网站的时候发现360极速浏览器ie7内核不兼容样式的问题

热门文章

  1. 【POJ1733】Parity game
  2. iOS 库 开发小结
  3. spring-boot日志操作
  4. JSP学习(JavaBean)
  5. 【isJson( jsonObj )】判断是否是JSON实例
  6. Angular6项目搭建
  7. 复合词 (Compund Word,UVa 10391)
  8. 56[LeetCode] .Merge Intervals
  9. POJ 2177 Ghost Busters(三维几何)
  10. Java学习个人备忘录之线程间的通信