题目:

DZY开始有 \(n\) 个点,现在他对这 \(n\) 个点进行了 \(m\) 次操作,对于第 \(i\) 个操作(从 \(1\) 开始编号)有可能的三种情况:

  • Add a b: 表示在 \(a\) 与 \(b\) 之间连了一条长度为 \(i\) 的边(注意,\(i\)是操作编号)。保证 \(1 \leq a, b \leq n\)。
  • Delete k: 表示删除了当前图中边权最大的k条边。保证 \(k\) 一定不会比当前图中边的条数多。
  • Return: 表示撤销第 \(i-1\) 次操作。保证第 \(1\) 次操作不是 Return 且第 \(i-1\) 次不是 Return 操作。

    请你在每次操作后告诉DZY当前图的最小生成树边权和。如果最小生成树不存在则输出 \(0\)。

题解:

首先我们来挖掘一下题目的性质.

  1. 加入的边权值递增
  2. 如果一条边被删除,那么所有大于这条边权值的边要么没被加入,要么已经被删除.

    所以我们可以直接大力可持久化并查集.

    \(O(mlog^2n)\) 做一些有理有据的底层优化应该能过掉.

但其实这道题没有那么复杂.

首先我们先忽略掉Return操作.

我们考虑维护动态加入和删除的并查集.

我们可以直接在\(O(mlogn)\)内完成.

但其实加上Return操作后对我们的做法也没有什么影响.

进行每一次操作的时候,我们首先检查一下下一操作是不是Return操作

如果不是Return我们就直接在现有的状态上进行修改.

如果是Return那么我们就计算出当前操作的影响,并不把这份影响加入到我们当前的状态中.

这样我们就可以直接用一维数组解决掉啦..

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch > '!');if(flag) x=-x;
}
const int maxn = 510010;
int fa[maxn],siz[maxn];
inline int find(int x){
while(fa[x] != x) x = fa[x];
return x;
}
int ope[maxn];
char s[12];
struct ope{
int op,u,v;
}op[maxn];
ll ans[maxn],sum[maxn];
int main(){
int n,m;read(n);read(m);
for(int i=1;i<=n;++i) fa[i] = i,siz[i] = 1;
for(int i=1;i<=m;++i){
scanf("%s",s);
if(*s == 'A'){
op[i].op = 1;
read(op[i].u);
read(op[i].v);
}else if(*s == 'D'){
op[i].op = 2;
read(op[i].u);
}else if(*s == 'R') op[i].op = 3;
}
int ecnt = 0,nodecnt = n;
for(int i=1;i<=m;++i){
if(op[i].op == 1){
if(op[i+1].op == 3){
if(nodecnt == 1) printf("%lld\n",ans[ecnt]);
else if(nodecnt == 2){
int x = find(op[i].u);
int y = find(op[i].v);
if(x == y) puts("0");
else printf("%lld\n",sum[ecnt] + i);
}else puts("0");
printf("%lld\n",ans[ecnt]);
++ i;
}else{
ans[ecnt+1] = ans[ecnt];
sum[ecnt+1] = sum[ecnt];
++ecnt;
int x = find(op[i].u);
int y = find(op[i].v);
if(x == y){
printf("%lld\n",ans[ecnt]);
ope[ecnt] = 0;
continue;
}
if(siz[x] > siz[y]) swap(x,y);
fa[x] = y;siz[y] += siz[x];ope[ecnt] = x;
sum[ecnt] += i;
if(--nodecnt == 1) ans[ecnt] = sum[ecnt];
printf("%lld\n",ans[ecnt]);
}
}else if(op[i].op == 2){
if(op[i+1].op == 3){
printf("%lld\n",ans[ecnt-op[i].u]);
++ i;
printf("%lld\n",ans[ecnt]);
}else{
for(int j=0;j<op[i].u;++j){
if(ope[ecnt] != 0){
int x = ope[ecnt];
++ nodecnt;
siz[fa[x]] -= siz[x];
fa[x] = x;
}-- ecnt;
}
printf("%lld\n",ans[ecnt]);
}
}
}
return 0;
}

uoj problem 14 DZY Loves Graph的更多相关文章

  1. 学长小清新题表之UOJ 14.DZY Loves Graph

    学长小清新题表之UOJ 14.DZY Loves Graph 题目描述 \(DZY\)开始有 \(n\) 个点,现在他对这 \(n\) 个点进行了 \(m\) 次操作,对于第 \(i\) 个操作(从 ...

  2. 【UER #1】[UOJ#12]猜数 [UOJ#13]跳蚤OS [UOJ#14]DZY Loves Graph

    [UOJ#12][UER #1]猜数 试题描述 这一天,小Y.小D.小C正在愉快地玩耍. 小Y是个数学家,他一拍脑袋冒出了一个神奇的完全平方数 n. 小D是个机灵鬼,很快从小Y嘴里套出了 n的值.然后 ...

  3. 【UOJ #14】【UER #1】DZY Loves Graph

    http://uoj.ac/problem/14 题解很好的~ 不带路径压缩的并查集能保留树的原本形态. 按秩合并并查集可以不用路径压缩,但是因为此题要删除,如果把深度当为秩的话不好更新秩的值,所以把 ...

  4. uoj #14.【UER #1】DZY Loves Graph

    http://uoj.ac/problem/14 由于加入的边权递增,可以直接运行kruskal并支持撤销,但这样如果反复批量删边和撤销,时间复杂度会退化,因此需要对删边操作加上延时处理,只有在删边后 ...

  5. Codeforces Round #FF (Div. 2):Problem A - DZY Loves Hash

    A. DZY Loves Hash time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  6. 2019.01.22 uoj#14. 【UER #1】DZY Loves Graph(并查集)

    传送门 题意简述: 要求支持以下操作: 在a与b之间连一条长度为i的边(i是操作编号):删除当前图中边权最大的k条边:表示撤销第 i−1次操作,保证第1次,第i−1 次不是撤回操作. 要求在每次操作后 ...

  7. UOJ14 DZY Loves Graph

    DZY开始有 nn 个点,现在他对这 nn 个点进行了 mm 次操作,对于第 ii 个操作(从 11 开始编号)有可能的三种情况: Add a b: 表示在 aa 与 bb 之间连了一条长度为 ii ...

  8. [UER #1] DZY Loves Graph

    题目描述 开始有 \(n\) 个点,现在对这 \(n\) 个点进行了 \(m\) 次操作,对于第 \(i\) 个操作(从 \(1\) 开始编号)有可能的三种情况: \(Add\) a b: 表示在 \ ...

  9. 【UER #1】DZY Loves Graph

    UOJ小清新题表 题目内容 UOJ链接 DZY开始有\(n\)个点,现在他对这\(n\)个点进行了\(m\)次操作,对于第\(i\)个操作(从\(1\)开始编号)有可能的三种情况: Add a b: ...

随机推荐

  1. Nginx教程

    Nginx教程 1.背景 介绍 Nginx是一个高性能的HTTP服务器,以及反向代理服务器 组成 Ngnix有内核和模块组成.微结构的内核根据配置文件将一个请求映射到一个location块中,该loc ...

  2. transport connector和network connector

    1 什么是transport connector 用于配置activemq服务器端和客户端之间的通信方式. 2 什么是network connector 用于配置activemq服务器之间的通信方式, ...

  3. Bootstrap学习-网格系统

    1.实现原理 网格系统的实现原理非常简单,仅仅是通过定义容器大小,平分12份(也有平分成24份或32份,但12份是最常见的),再调整内外边距,最后结合媒体查询,就制作出了强大的响应式网格系统.Boot ...

  4. [luogu4255]公主の#18文明游戏

    [luogu4255]公主の#18文明游戏 luogu 发现没有连边,只有删边? 考虑倒着做 开map记M[i][j]表示编号为i的并查集,信仰j的人数 s[i]表示编号为i的并查集的总人数 首先询问 ...

  5. 3.写一个hello world页面

    经过1和2的学习,现在已经可以正常启动Django了,这一节说怎么写一个hello world页面,所有的环境基础就是1和2中搭建的 1.在app模块中添加页面 具体为 hello_django\he ...

  6. Java的接口和抽象类(转发:http://www.importnew.com/18780.html)

    深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...

  7. C#读取excel 找不到可安装的ISAM

    实在没有办法了 就仔细的查看了 一下数据链接字符串: string strConn = "Provider=Microsoft.Jet.Oledb.4.0;Data Source=" ...

  8. Python核心编程 课后练习 第二章

    2.4 使用raw_input()函数得到用户输入. (a) 创建一段脚本使用raw_input()函数从用户输入得到一个字符串, 然后显示这个用户杠杠输入的字符串. #coding = utf-8 ...

  9. java入门了解13

    小知识点: 网络编程:主要解决计算机间数据传输 不需要html页面可以达到数据传输:QQ,微信 网页编程:继续Html页面基础上数据交互:OA,天猫... java方向:web方向,annrod常用S ...

  10. 算法(Algorithms)第4版 练习 1.5.15

    用归纳法推导: 1.height = 0时,成立,其level 0的节点个数为C(0,0)=1. height = 1时,成立,其level 0的节点个数为C(1,0)=1,其level 1的节点个数 ...