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

题目描述

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

\(Add\ a\ b:\) 表示在 \(a\) 与 \(b\) 之间连了一条长度为 \(i\)的边(注意,\(i\)是操作编号)。保证 \(1≤a,b≤n\)。

\(Delete\ k:\) 表示删除了当前图中边权最大的\(k\)条边。保证$ k$一定不会比当前图中边的条数多。

\(Return\): 表示撤销第 \(i−1\)次操作。保证第 \(1\) 次操作不是 \(Return\) 且第 \(i−1\)次不是 Return 操作。

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

输入格式

第一行两个正整数 \(n,m\)。表示有 \(n\) 个点 $m $个操作。 接下来 \(m\)行每行描述一个操作。

输出格式

对于每一个操作输出一行一个整数表示当前最小生成树边权和。

样例一

input

2 2

Add 1 2

Return

output

1

0

样例二

input

5 10

Add 2 1

Add 3 2

Add 4 2

Add 5 2

Add 2 3

Return

Delete 1

Add 2 3

Add 5 2

Return

output

0

0

0

10

10

10

0

0

15

0

样例三

见样例数据下载

限制与约定

测试点编号 n m 其他
\(1、2、3\) \(n≤10^3\) \(m≤10^3\) 只有\(Add\)操作
\(4\) \(n≤2×10^5\) \(m≤2×10^5\) 只有\(Add\)操作
\(5\) \(n≤3×10^5\) \(m≤5×10^5\)
\(6\) \(n≤2×10^5\) \(m≤2×10^5\) 没有\(Return\)操作
\(7\) \(n≤3×10^5\) \(m≤5×10^5\)
\(8\) \(n≤2×10^5\) \(m≤2×10^5\)
\(9、10\) \(n≤3×10^5\) \(m≤5×10^5\)

时间限制:\(1s\)

空间限制:\(64MB\)

分析

我们认真分析题目的话,不难得出以下结论

\(1\)、此题的空间限制较小,如果用可持久化数据 结构很可能会超空间

\(2\)、边权是从小到大加入的,因此如果之前加的边已经可以生成一棵树,那么之后加的边不会产生影响

\(3\)、题目中没有要求强制在线,而且有\(Return\)操作,可以考虑离线

对于\(Add\)操作,我们可以像最小生成树用并查集维护

如果当前的两个节点已经处于一个联通块,那么它们之间的权值一定小于新加入的权值,我们不去管他

如果两个节点属于一个联通块,我们就把两个节点并在一起

对于\(Delete\)操作,路径压缩并查集是无法解决的,因为它会打乱原来的结果,所以我们要用到按秩合并的并查集

所谓按秩合并,就是把深度小的并到深度大的上面或者是把子树小的并到子树大的上面

对于\(Return\)操作,因为是离线处理,所以就好办多了

如果撤销加边操作的话,我们把撤销操作改为删边操作即可

如果撤销删除操作,我们就不去删边,而是用一个\(ans\)数组去记录有\(k\)条边时的最小生成树的权值

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
typedef long long ll;//不开long long见祖宗
inline ll read(){
register ll x=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1LL)+(x<<3LL)+(ch^48);
ch=getchar();
}
return x*f;
}//快读卡常
struct asd{
char jls[3];
ll jla,jlb;
}b[maxn];//离线用结构体
ll fa[maxn],rk[maxn],shuyu[maxn],sta[maxn],top;
ll ans[maxn],n,m,tot,cnt,anscnt;
//fa:并查集父亲节点,rk:子树大小,shuyu:记录某条边属于哪一个节点,sta:存储使用过的边
//ans:记录边数为k时最小生成树的权值和,tot:记录最小生成树的权值,cnt:记录最小生成树的边数,anscnt:记录统计过的答案的个数
ll zhao(ll xx){
if(xx==fa[xx]) return xx;
return zhao(fa[xx]);
}//找到祖先节点
void bing(ll xx,ll yy,ll w){
ll aa=zhao(xx),bb=zhao(yy);
if(aa==bb){
shuyu[w]=-1;
return;
}
if(rk[aa]<rk[bb]) swap(aa,bb);
rk[aa]+=rk[bb];
fa[bb]=aa;
shuyu[w]=bb;
tot+=w,cnt++;
}//按秩合并
void shanchu(ll val){
ll xx=shuyu[val];
ll yy=fa[xx];
rk[yy]-=rk[xx];
fa[xx]=xx;
cnt--,tot-=val;
}//删边
int main(){
n=read(),m=read();
for(ll i=1;i<=n;i++){
fa[i]=i,rk[i]=1;
}
for(ll i=1;i<=m;i++){
scanf("%s",b[i].jls);
if(b[i].jls[0]=='A'){
b[i].jla=read(),b[i].jlb=read();
} else if(b[i].jls[0]=='D'){
b[i].jla=read();
}
}
//初始化+读入
for(ll i=1;i<=m;i++){
if(b[i].jls[0]=='A'){
bing(b[i].jla,b[i].jlb,i);
sta[++top]=i;
if(cnt<n-1) ans[++anscnt]=0;
else ans[++anscnt]=tot;
if(b[i+1].jls[0]=='R'){
b[i+1].jls[0]='D';
b[i+1].jla=1;
}
printf("%lld\n",ans[anscnt]);
} else if(b[i].jls[0]=='D'){
if(b[i+1].jls[0]=='R'){
printf("%lld\n%lld\n",ans[anscnt-b[i].jla],ans[anscnt]);
continue;
}
while(b[i].jla--){
ll now=sta[top--];
anscnt--;
if(shuyu[now]!=-1){
shanchu(now);
}
}
if(cnt<n-1) ans[anscnt]=0;
else ans[anscnt]=tot;
printf("%lld\n",ans[anscnt]);
}
}
return 0;
}

学长小清新题表之UOJ 14.DZY Loves Graph的更多相关文章

  1. 学长小清新题表之UOJ 180.实验室外的攻防战

    学长小清新题表之UOJ 180.实验室外的攻防战 题目描述 时针指向午夜十二点,约定的日子--\(2\)月\(28\)日终于到来了.随着一声枪响,伏特跳蚤国王率领着他的跳蚤大军们包围了 \(picks ...

  2. 学长小清新题表之UOJ 31.猪猪侠再战括号序列

    学长小清新题表之UOJ 31.猪猪侠再战括号序列 题目描述 大家好我是来自百度贴吧的_叫我猪猪侠,英文名叫\(\_CallMeGGBond\). 我不曾上过大学,但这不影响我对离散数学.复杂性分析等领 ...

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

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

  4. uoj problem 14 DZY Loves Graph

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

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

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

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

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

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

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

  8. 【思维题 线段树】cf446C. DZY Loves Fibonacci Numbers

    我这种maintain写法好zz.考试时获得了40pts的RE好成绩 In mathematical terms, the sequence Fn of Fibonacci numbers is de ...

  9. 【Luogu3676】小清新数据结构题(动态点分治)

    [Luogu3676]小清新数据结构题(动态点分治) 题面 洛谷 题解 先扯远点,这题我第一次看的时候觉得是一个树链剖分+线段树维护. 做法大概是这样: 我们先以任意一个点为根,把当前点看成是一棵有根 ...

随机推荐

  1. 6.ALOHA协议

    动态媒体接入控制/多点接入特点:信道并非在用户通信时固定分配给用户. 一.纯ALOHA协议 纯 ALOHA协议思想:不监听信道,不按时间槽发送,随机重发.想发就发 二.时隙ALOHA协议 时隙 ALO ...

  2. Fastjson到了说再见的时候了

    生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...

  3. vue传参方式

    //query传参,使用name跳转   this.$router.push({       name:'second',       query: {         queryId:'201808 ...

  4. Python Python Python 100个练手项目

    1.淘宝模拟登录2.天猫商品数据爬虫3.爬取淘宝我已购买的宝贝数据4.每天不同时间段通过微信发消息提醒女友5.爬取5K分辨率超清唯美壁纸6.爬取豆瓣排行榜电影数据(含GUI界面版)7.多线程+代理池爬 ...

  5. 4.pandas的进阶查询

    简单的查询其实根本不能满足实际开发的需求 需求可能是让你查一下2018年的销售额啊,2019年温度超过30℃的天数啊等等的 这些需求都是有异曲同工的,就是带条件的查询 这里我们先自己设计一个表格,并将 ...

  6. 数字转字符串&&字符串转数字

    一开始写错了呜呜呜 先是<< 再是>>

  7. PHP xml_set_object() 函数

    定义和用法 xml_set_object() 函数允许在对象中使用 XML 解析器.高佣联盟 www.cgewang.com 如果成功,该函数则返回 TRUE.如果失败,则返回 FALSE. 语法 x ...

  8. 利用python进行数据分析PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书

    点击获取提取码:hi2j 内容简介 [名人推荐] "科学计算和数据分析社区已经等待这本书很多年了:大量具体的实践建议,以及大量综合应用方法.本书在未来几年里肯定会成为Python领域中技术计 ...

  9. 【NOI2005】聪聪与可可 题解(最短路+期望DP)

    前言:学长讲的太神了:自己还能推出来DP式子,挺开心. -------------------------- 题目链接 题目大意:给定一张含有$n$个结点$m$条边的无向连通图.现在聪聪在点$s$,可 ...

  10. python8.4景区买票

    from threading import Threadimport threadinglock=threading.Lock()num=100#定义买票方法def sale(name): lock. ...