洛谷 P2542 [AHOI2005]航线规划(Link-cut-tree)
题面
题解
离线处理+LCT
有点像星球大战
我们可以倒着做,断边变成连边
我们可以把边变成一个点
连边时,如果两个点本身不联通,就\(val\)赋为\(1\),并连接这条边
如果,两个点本身就联通,那么就不连接这条边,把两点之间的\(val\)全部赋为\(0\)
\(ans\)就是求两点之间的\(sum(val)\)
Code
#include<bits/stdc++.h>
#define LL long long
#define RG register
using namespace std;
inline int gi() {
RG int x = 0; RG char c = getchar(); bool f = 0;
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') c = getchar(), f = 1;
while (c >= '0' && c <= '9') x = x*10+c-'0', c = getchar();
return f ? -x : x;
}
const int N = 52000;
struct node {
int ch[2], f, sum, rev, v, ly;
}t[N<<2];
bool isroot(int x) {
return t[t[x].f].ch[0] != x && t[t[x].f].ch[1] != x;
}
inline int get(int x) {
return t[t[x].f].ch[1] == x;
}
inline void pushup(int x) {
t[x].sum = t[t[x].ch[0]].sum+t[t[x].ch[1]].sum+t[x].v;
}
void rotate(int x) {
int y = t[x].f, z = t[y].f, k = get(x);
if (!isroot(y))
t[z].ch[get(y)] = x;
t[x].f = z;
t[t[x].ch[k^1]].f = y; t[y].ch[k] = t[x].ch[k^1];
t[y].f = x; t[x].ch[k^1] = y;
pushup(y);
return ;
}
int top, S[N<<2];
inline void putly(int x) {t[x].ly = 1; t[x].sum = t[x].v = 0;}
void pushdown(int x) {
if (t[x].rev) {
swap(t[x].ch[0], t[x].ch[1]);
if (t[x].ch[0]) t[t[x].ch[0]].rev ^= 1;
if (t[x].ch[1]) t[t[x].ch[1]].rev ^= 1;
t[x].rev = 0;
}
if (t[x].ly) {
if (t[x].ch[0]) putly(t[x].ch[0]);
if (t[x].ch[1]) putly(t[x].ch[1]);
t[x].ly = 0;
}
return ;
}
void splay(int x) {
S[top=1] = x;
for (int i = x; !isroot(i); i = t[i].f) S[++top] = t[i].f;
for (int i = top; i; i--) pushdown(S[i]);
while (!isroot(x)) {
int y = t[x].f;
if (!isroot(y))(get(x)^get(y)) ? rotate(x):rotate(y);
rotate(x);
}
pushup(x);
return ;
}
void access(int x) {for (int y=0;x;y=x,x=t[x].f) splay(x),t[x].ch[1]=y,pushup(x);}
void makeroot(int x){access(x),splay(x),t[x].rev ^= 1;}
void split(int x, int y){makeroot(x),access(y),splay(y);}
void link(int x, int y) {makeroot(x);t[x].f = y;}
int findroot(int x) {access(x); splay(x);while (t[x].ch[0]) x = t[x].ch[0];return x;}
struct Line {
int u, v;
bool flag;
}E[N<<2];
map<pair<int, int>, int> M;
struct question {
int op, ans, u, v;
}q[N];
int main() {
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
int n = gi(), m = gi();
for (int i = 1; i <= m; i++) {
int u = gi(), v = gi();
if (u > v) swap(u, v);
E[i] = (Line) {u, v, 0};
t[i+n].v = 1;
M[make_pair(u, v)] = i;
}
int cnt = 0;
for (;;) {
int c = gi(); if (c == -1) break;
int u = gi(), v = gi(); if (u > v) swap(u, v);
q[++cnt] = (question) {c, 0, u, v};
if (!c) E[q[cnt].ans = M[make_pair(u, v)]].flag = 1;
}
for (int i = 1; i <= m; i++)
if (!E[i].flag) {
int u = E[i].u, v = E[i].v;
if (findroot(u) != findroot(v))
link(u, i+n), link(v, i+n);
else {
split(u, v);
putly(v);
}
}
for (int i = cnt; i; i--) {
if (q[i].op) {
int u = q[i].u, v = q[i].v;
split(u, v);
q[i].ans = t[v].sum;
}
else {
int u = q[i].u, v = q[i].v;
if (findroot(u) != findroot(v))
link(u, q[i].ans+n), link(v, q[i].ans+n);
else {
split(u, v);
putly(v);
}
}
}
for (int i = 1; i <= cnt; i++)
if (q[i].op)
printf("%d\n", q[i].ans);
return 0;
}
洛谷 P2542 [AHOI2005]航线规划(Link-cut-tree)的更多相关文章
- 洛谷 P2542 [AHOI2005]航线规划 解题报告
P2542 [AHOI2005]航线规划 题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系--一个巨大的由千百万星球构成的Samuel星系 ...
- 洛谷P2542 [AHOI2005]航线规划(LCT,双连通分量,并查集)
洛谷题目传送门 太弱了不会树剖,觉得LCT好写一些,就上LCT乱搞,当LCT维护双连通分量的练手题好了 正序删边是不好来维护连通性的,于是就像水管局长那样离线处理,逆序完成操作 显然,每个点可以代表一 ...
- 洛谷 P2542 [AHOI2005]航线规划 树链剖分_线段树_时光倒流_离线
Code: #include <map> #include <cstdio> #include <algorithm> #include <cstring&g ...
- 【刷题】洛谷 P3690 【模板】Link Cut Tree (动态树)
题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...
- 洛谷P3690 【模板】Link Cut Tree (LCT)
题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...
- [洛谷P3690]【模板】Link Cut Tree (动态树)
题目大意:给定$n$个点以及每个点的权值,要你处理接下来的$m$个操作.操作有$4$种.操作从$0到3编号.点从1到n编号. $0,x,y$:代表询问从$x$到$y$的路径上的点的权值的$xor$和. ...
- 洛谷 P3690 【模板】Link Cut Tree (动态树) || bzoj 3282: Tree
https://blog.csdn.net/saramanda/article/details/55253627 https://blog.csdn.net/CHHNZ/article/details ...
- P2542 [AHOI2005]航线规划 LCT维护双连通分量
\(\color{#0066ff}{ 题目描述 }\) 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系--一个巨大的由千百万星球构成的Samuel ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
随机推荐
- Docker学习笔记_初装的Centos无ifconfig
新创建了centos容器,使用ifconfig,报无此命令. 解决办法,使用yum进行安装ifconfig 1.yum search ifconfig 2.yum install net-tools. ...
- 面试题:基础数据类型 包装类 int Integer
因为在学习集合时知道集合里存放的对象都是Object类型,取出的时候需要强制类型转换为目标类型(使用泛型集合不需要),如int a = (Integer)arrayList.get(0):然后我们就会 ...
- C#中的异步编程Async 和 Await
谈到C#中的异步编程,离不开Async和Await关键字 谈到异步编程,首先我们就要明白到底什么是异步编程. 平时我们的编程一般都是同步编程,所谓同步编程的意思,和我们平时说的同时做几件事情完全不同. ...
- maven构建非法字符解决办法
CI使用maven做版本构建时候碰到了一个问题,有个java源码始终编译报错,错误发生在文件第一行. 出错内容是: ***.java:[1,1] 非法字符: \65279 后面上网看了,原来是文件编码 ...
- oracle数据库之分组查询
本章内容和大家分享的是数据当中的分组查询.分组查询复杂一点的是建立在多张表的查询的基础之上,(我们在上一节课的学习中已经给大家分享了多表查询的使用技巧,大家可以自行访问:多表查询1 多表查询2)而在 ...
- ubuntu 14.04编译安装xen4.4总结
1. 安装环境 操作系统:ubuntu14.04 xen版本:xen4.4 2. 依赖包的安装 在安装xen之前先进行依赖包的安装,在不停得尝试之后,总结出以下需要安装的依赖包. sudo apt-g ...
- myeclipse 8.0 注册码
Subscriber:accptechSubscription Code:nLR8ZC-855550-6765855429037911 Subscriber:Hello World Subscript ...
- Django中使用后台网站模板
背景: 一直想自己开发一个网站,但是前端知识又不多,好在有模板可以使用,下载地址:https://download.csdn.net/download/wjgccsdn/10843808 开干: ...
- logback-记录日志
一:根节点<configuration>包含的属性: scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true. scanPeriod: 设置监测配 ...
- 复制构造函数被调用的三种情况------新标准c++程序设计
1.当用一个对象去初始化同类的另一个对象时,会引发复制构造函数被调用.例如,下面的两条语句都会引发复制构造函数的调用,用以初始化c2. C c2 (c1); C c2=c1; 这两条语句是等价的.注意 ...