DZY开始有 nn 个点,现在他对这 nn 个点进行了 mm 次操作,对于第 ii 个操作(从 11 开始编号)有可能的三种情况:

  1. Add a b: 表示在 aa 与 bb 之间连了一条长度为 ii 的边(注意,ii是操作编号)。保证 1≤a,b≤n1≤a,b≤n。
  2. Delete k: 表示删除了当前图中边权最大的k条边。保证 kk 一定不会比当前图中边的条数多。
  3. Return: 表示撤销第 i−1i−1 次操作。保证第 11 次操作不是 Return 且第 i−1i−1 次不是 Return 操作。

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

输入格式

第一行两个正整数 n,mn,m。表示有 nn 个点 mm 个操作。 接下来 mm 行每行描述一个操作。

输入格式

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

样例一

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

样例三

见样例数据下载

正解:并查集+各种奇怪维护

解题报告:

  调试了两个多小时才AC,而且还蒯了别人的题解。

  传送门:http://vfleaking.blog.uoj.ac/blog/15

  我讲不太清楚,直接看vfk的博客吧。

 //It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#ifdef WIN32
#define OT "%I64d"
#else
#define OT "%lld"
#endif
using namespace std;
typedef long long LL;
const int MAXM = ;
int n,m,cnt;//cnt统计树边
LL ans;
int father[MAXM],last[MAXM];//分别表示最小生成树中的所在块的祖先和这条边断掉之后的所在块的祖先(前提,这条边在最小生成树中)
//int stack[MAXM];
int size[MAXM],top;
char ch[];
LL num[MAXM];
vector<int>q;
struct ask{
int type,x,y;
}Q[MAXM]; inline int getint()
{
int w=,q=;
char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar();
if (c=='-') q=, c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar();
return q ? -w : w;
} inline int find(int x){
if(father[x]!=x) return find(father[x]);
return father[x];
} inline void delet(int x){
int u;
while(x--) {
u=q[q.size()-]; q.pop_back();
//u=stack[top]; top--;
if(last[u]!=-) {
ans-=u; cnt--; int y=father[u];
while(y)
{
size[y]-=size[u];
if(y==father[y]) break;
}
//if(father[x]) size[father[x]]-=size[x];
father[last[u]]=last[u];
}
}
} inline void work(){
n=getint(); m=getint();
for(int i=;i<=m;i++) {
scanf("%s",ch);
if(ch[]=='A') Q[i].type=,Q[i].x=getint(),Q[i].y=getint();
else if(ch[]=='D') Q[i].type=,Q[i].x=getint();
else Q[i].type=;
}
for(int i=;i<=n;i++) father[i]=i,size[i]=;
int x,y;
for(int i=;i<=m;i++) {
if(Q[i].type==) {
//stack[++top]=i;
q.push_back(i);
x=find(Q[i].x); y=find(Q[i].y);
if(x!=y) {//加入最小生成树,后面的肯定不如前面的编号小的更优
if(size[x]>size[y]) swap(x,y);//交换,按秩
last[i]=x;
father[x]=y; size[y]+=size[x];
ans+=i; cnt++;
}
else last[i]=-;//不在最小生成树中
}
else if(Q[i].type==) {
if(Q[i+].type==) {
//printf("%lld\n",num[top-Q[i].x]);
printf("%lld\n",num[q.size()-Q[i].x]);
continue;
}else delet(Q[i].x);
}
else {
if(Q[i-].type==) delet();
} if(cnt==n-) {//构成最小生成树
//num[top]=ans;
num[q.size()]=ans;
printf("%lld\n",ans);
}
else {
//num[top]=0;
num[q.size()]=;
printf("0\n"); }
}
} int main()
{
work();
return ;
}

最新文章

  1. 动态导入(import)和静态导入(import)的区别
  2. 清空highcharts数据
  3. AX2012 R3升级CU8的一些错误
  4. Vim 插件之 NERDTree
  5. java多线程:jdk并发包的总结(转载)
  6. Yii框架-Smarty-整合
  7. Android XML文档解析(一)——SAX解析
  8. HDU 1559 最大子矩阵 (DP)
  9. 环信 之 iOS 客户端集成四:集成UI
  10. IOS 私有变量 私有属性的书写方法
  11. MATLAB—求直线或者线段之间的交点坐标
  12. 扩展方法、委托和Lambda
  13. linux 环境RPM 安装MYSQL5.6
  14. Chrome插件 postman的使用方法详解!最全面的教程
  15. LuaJit转义的问题
  16. iis部署 .net core webapi
  17. J2EE从下载到配置成功
  18. Selenium报错整理
  19. tmp_table_size ---&gt; 优化 MYSQL 经验总结
  20. 怎样将Arranged_2压入General_Polygon_set_2中

热门文章

  1. php cmd 不能利用$_COOKIE 的处理 通过文件来暂存字符串
  2. &lt;2013 06 29&gt; In Deutschland. Thinking in Mechanism, EE, CS, etc.
  3. ECMAScript6面对大于0xFFFF的Unicode字符如何正确返回长度
  4. element-ui中下拉菜单中的@click事件不会触发的问题
  5. python面试题(六)
  6. java基础—Hashtable,HashMap,TreeMap的差别
  7. nginx 与 lua 开发笔记
  8. Traverse the dict in Python
  9. django-admin 登录之后显示页面,表是否显示
  10. (转) GIS 中地理坐标和屏幕坐标的标准转换方法