「CSA72」MST
「CSA72」MST
题目大意:有一个大小为 \(n\) 的无向完全图,\(x, y\) 之间的边权值为 \(a[\min(x,y)][\max(x,y)]\) ,初始为0,进行 \(m\) 次修改,每次将一个矩形的权值加上 \(w\) ,求出最后这张完全图的最小生成树的边权和。\(n,m \leq 100000\)。
解题思路:用 Borůvka 求最小生成树,每一轮求出每一个点所在联通块向外连的一条边权最小的边,并用线段树+扫描线维护最小值以及最小值所在的联通块编号。为了找到不在同一个联通块内的边权最小的边,所以额外记一个次小值,并时刻保证次小值所在的联通块编号与最小值不是同一个,那么要连出去的最小的边一定在这两者之间,总复杂度 \(O(nlog^2n)\)。
code
/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf ((ll)(1e16))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T & x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
#define par pair<ll, ll>
#define fi first
#define se second
const int N = 100005;
struct chino{ int t, l, r, w; } q[N<<2];
int fa[N], n, m, tot, cnt; ll ans;
par tmp[N];
inline int ask(int x){ return x == fa[x] ? x : fa[x] = ask(fa[x]); }
struct Node{
int id[2]; ll val[2];
inline Node(){ val[0] = val[1] = inf, id[0] = id[1] = 0; }
inline Node operator + (const int &w){
Node res = *this;
return res.val[0] += w, res.val[1] += w, res;
}
inline Node operator + (const Node &A){
Node res, rhs;
res = (val[0] < A.val[0] ? *this : A);
rhs = (val[0] < A.val[0] ? A : *this);
for(int i = 0; i < 2; i++)
if(ask(rhs.id[i]) != ask(res.id[0]) && rhs.val[i] < res.val[1])
res.val[1] = rhs.val[i], res.id[1] = rhs.id[i];
return res;
}
};
namespace Seg{
#define lson (u << 1)
#define rson (u << 1 | 1)
#define mid (l + r >> 1)
Node mn[N<<2]; ll tag[N<<2];
inline void build(int u, int l, int r){
tag[u] = 0;
if(l == r){
mn[u].val[0] = 0, mn[u].val[1] = inf;
mn[u].id[0] = l, mn[u].id[1] = 0; return;
}
build(lson, l, mid), build(rson, mid + 1, r);
mn[u] = mn[lson] + mn[rson];
}
inline void pushdown(int u){
if(!tag[u]) return;
mn[lson] = mn[lson] + tag[u], mn[rson] = mn[rson] + tag[u];
tag[lson] += tag[u], tag[rson] += tag[u], tag[u] = 0;
}
inline void change(int u, int l, int r, int L, int R, ll w){
if(l >= L && r <= R) return (void) (mn[u] = mn[u] + w, tag[u] += w);
pushdown(u);
if(L <= mid) change(lson, l, mid, L, R, w);
if(mid < R) change(rson, mid + 1, r, L, R, w);
mn[u] = mn[lson] + mn[rson];
}
}
inline void Bruasolve(){
Seg::build(1, 1, n);
for(register int i = 1; i <= n; i++) tmp[i].fi = inf, tmp[i].se = 0;
int p = 1;
for(register int i = 1; i <= n; i++){
while(p <= cnt && q[p].t == i)
Seg::change(1, 1, n, q[p].l, q[p].r, q[p].w), p++;
Node x = Seg::mn[1];
par now = (ask(x.id[0]) != ask(i)) ? make_pair(x.val[0], x.id[0]) : make_pair(x.val[1], x.id[1]);
if(now.fi < tmp[ask(i)].fi) tmp[ask(i)] = now;
}
for(register int i = 1; i <= n; i++) if(fa[i] == i){
if(ask(tmp[i].se) != i && tmp[i].se) tot++, ans += tmp[i].fi, fa[ask(tmp[i].se)] = i;
}
}
inline bool cmp(const chino &A, const chino &B){ return A.t < B.t; }
signed main(){
read(n), read(m);
for(int i = 1, X1, X2, Y1, Y2, w; i <= m; i++){
read(X1), read(X2), read(Y1), read(Y2), read(w);
q[++cnt] = ((chino){X1, Y1, Y2, w});
q[++cnt] = ((chino){X2 + 1, Y1, Y2, -w});
q[++cnt] = ((chino){Y1, X1, X2, w});
q[++cnt] = ((chino){Y2 + 1, X1, X2, -w});
}
sort(q + 1, q + cnt + 1, cmp);
for(int i = 1; i <= n; i++) fa[i] = i;
while(tot < n - 1) Bruasolve(); cout << ans << endl;
return 0;
}
「CSA72」MST的更多相关文章
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- 「C++」理解智能指针
维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...
- 「JavaScript」四种跨域方式详解
超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...
- 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management
写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...
- 「2014-3-18」multi-pattern string match using aho-corasick
我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...
- 「2014-3-17」C pointer again …
记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...
- 「2014-3-13」Javascript Engine, Java VM, Python interpreter, PyPy – a glance
提要: url anchor (ajax) => javascript engine (1~4 articles) => java VM vs. python interpreter =& ...
随机推荐
- android 自定义View属性
在android开发过程中,用到系统的View时候可以通过XML来定义一些View的属性.比如ImageView: android:src 和android:scaleType为ImageVie ...
- 不相交集ADT--链表实现
每一个集合用用一个链表来表示.链表的第一个对象作为它所在集合的代表.链表中每个对象都包含一个集合成员,一个指向下一个对象的指针,以及指向代表的指针.每个链表含head和tail指针,head指向链表的 ...
- 2-Python基础语法-内存管理-运算符-程序控制
目录 1 Python 基础语法 1.1 注释 1.2 缩进 1.3 续行 1.4 标识符 1.5 转义序列 1.6 数字 1.7 字符串 1.8 其他 2 Python 运算符 2.1 赋值运算符 ...
- 自动化测试===adb 解锁手机的思路
在adb里有模拟按键/输入的命令 比如使用 adb shell input keyevent <keycode> 命令,不同的 keycode 能实现不同的功能,完整的 keycode 列 ...
- python使用requests模块模拟登陆知乎
from bs4 import BeautifulSoup import requests import time def captcha(captcha_data): with open(" ...
- Spring Boot 在接收上传文件时,文件过大异常处理问题
Spring Boot 在接收上传文件时,文件过大时,或者请求过大,spring内部处理都会抛出异常,并且捕获不到. 虽然可以通过调节配置,增大 请求的限制值. 但是还是不太方便. 之所以捕获不到异常 ...
- Codeforces Round #423 Div. 2 C-String Reconstruction(思维)
题目大意:告诉你n个字符串以及这些字符串在字符串s中出现的位置(x1,x2.....xn),要求在满足上述条件的情况下,求出字典序最小的字符串s. 解题思路:主要问题是,如果直接模拟是会超时的,比如v ...
- golang基础之三-字符串,时间,流程控制,函数
strings和strconv的使用 strings strings.HasPrefix(s string,preffix string) bool:判断字符串s是否以prefix开头 stirngs ...
- LeetCode765. Couples Holding Hands
N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum numb ...
- 字符串匹配的KMP算法(如何实现还需静下心来细看)
第一部分:KMP算法的理解(转:http://kb.cnblogs.com/page/176818/) 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB AB ...