题目传送门

题解:

对整个修改的区间进行分治。对于当前修改区间来说,我们对整幅图中将要修改的边权都先改成-inf,跑一遍最小生成树,然后对于一条树边并且他的权值不为-inf,那么这条边一定就是树边了。然后我们把这些点都缩成一个点。然后,我们继续对当前修改区间来说,我们把要修改的边的边权都修改成inf,跑一遍最小生成树,然后对于一条非树边来说,他的边权不为inf,那么这条边一点是非树边了,然后我们每层缩点,减边,这样图就会越来越小,然后当l == r的时候,我们还原修改操作,最后把跑最小生成树计算答案。

一道神奇的cdq题目。

代码:

 #include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
struct Node{
int u, v, c, id;
bool operator < (const Node & x) const{
return c < x.c;
}
}e[][N], f[N], g[N];
int a[N], b[N], ct[N], mapid[N];
int pre[N];
int to[N];
void link(int u, int v){
mapid[to[v]] = ;
mapid[u] = v;
to[v] = u;
}
int Find(int x){
if(x == pre[x]) return x;
return pre[x] = Find(pre[x]);
}
LL ans[N];
void Clear(int tot){
for(int i = ; i <= tot; i++){
pre[f[i].u] = f[i].u;
pre[f[i].v] = f[i].v;
}
}
void contraction(int &tot, LL &sum){
Clear(tot);
sort(f+, f++tot);
int u, v, zz = ;
for(int i = ; i <= tot; i++){
u = Find(f[i].u), v = Find(f[i].v);
if(u != v){
pre[u] = v;
if(f[i].c != -inf){
sum += f[i].c;
g[++zz] = f[i];
}
}
}
Clear(tot);
for(int i = ; i <= zz; i++){
u = Find(g[i].u); v = Find(g[i].v);
pre[u] = v;
}
zz = ;
for(int i = ; i <= tot; i++){
u = Find(f[i].u), v = Find(f[i].v);
if(u != v){
f[++zz] = f[i];
f[zz].u = u;
f[zz].v = v;
mapid[f[i].id] = zz;
}
}
tot = zz;
return ;
}
void reduction(int &tot){
Clear(tot);
sort(f+, f++tot);
int u, v, zz = ;
for(int i = ; i <= tot; i++){
u = Find(f[i].u); v = Find(f[i].v);
if(u != v){
pre[u] = v;
f[++zz] = f[i];
}
else if(f[i].c == inf)
f[++zz] = f[i];
}
tot = zz;
return ;
}
void cdq(int l, int r, int now, int tot, LL sum){
if(l == r) ct[a[l]] = b[l];
for(int i = ; i <= tot; i++){
e[now][i].c = ct[e[now][i].id];
mapid[e[now][i].id] = i;
//link(e[now][i])
f[i] = e[now][i];
}
if(l == r){
ans[l] = sum;
Clear(tot);
sort(f+, f++tot);
int u, v;
for(int i = ; i <= tot; i++){
u = Find(f[i].u), v = Find(f[i].v);
if(u != v){
pre[u] = v;
ans[l] += f[i].c;
}
}
return ;
}
for(int i = l; i <= r; i++) f[mapid[a[i]]].c = -inf;
contraction(tot, sum);
for(int i = l; i <= r; i++) f[mapid[a[i]]].c = inf;
reduction(tot);
for(int i = ; i <= tot; i++) e[now+][i] = f[i];
int mid = l+r >> ;
cdq(l, mid, now+, tot, sum);
cdq(mid+, r, now+, tot, sum); }
int main(){
int n, m, q;
scanf("%d%d%d", &n, &m, &q);
for(int i = ; i <= m; i++){
scanf("%d%d%d", &e[][i].u, &e[][i].v, &e[][i].c);
e[][i].id = i;
ct[i] = e[][i].c;
}
for(int i = ; i <= q; i++)
scanf("%d%d", &a[i], &b[i]);
cdq(,q,,m,);
for(int i = ; i <= q; ++i)
printf("%lld\n", ans[i]);
return ;
}

bzoj 2001 CITY 城市建设 cdq分治的更多相关文章

  1. bzoj 2001: City 城市建设 cdq

    题目 PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁.Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费.Louis希望建造最少的道路使得国内所有 ...

  2. BZOJ2001 [Hnoi2010]City 城市建设 CDQ分治

    2001: [Hnoi2010]City 城市建设 Time Limit: 20 Sec  Memory Limit: 162 MB Description PS国是一个拥有诸多城市的大国,国王Lou ...

  3. BZOJ 2001: [Hnoi2010]City 城市建设

    2001: [Hnoi2010]City 城市建设 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1132  Solved: 555[Submit][ ...

  4. 【BZOJ2001】 [Hnoi2010]City 城市建设

    BZOJ2001 [Hnoi2010]City 城市建设 Solution 我们考虑一下这个东西怎么求解? 思考无果...... 咦? 好像可以离线cdq,每一次判断一下如果这条边如果不选就直接删除, ...

  5. Luogu 3810 & BZOJ 3262 陌上花开/三维偏序 | CDQ分治

    Luogu 3810 & BZOJ 3263 陌上花开/三维偏序 | CDQ分治 题面 \(n\)个元素,每个元素有三个值:\(a_i\), \(b_i\) 和 \(c_i\).定义一个元素的 ...

  6. BZOJ2001 [Hnoi2010]City 城市建设 【CDQ分治 + kruskal】

    题目链接 BZOJ2001 题解 CDQ分治神题... 难想难写.. 比较朴素的思想是对于每个询问都求一遍\(BST\),这样做显然会爆 考虑一下时间都浪费在了什么地方 我们每次求\(BST\)实际上 ...

  7. BZOJ2001: [Hnoi2010]City 城市建设

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2001 cdq分治+重建图. 可以保留当前一定会被选的非修改边然后把点缩起来.这样的话每次点数至 ...

  8. 【bzoj2001】 Hnoi2010—City 城市建设

    http://www.lydsy.com/JudgeOnline/problem.php?id=2001 (题目链接) 题意 给出一张无向图,$m$组操作,每次修改一条边的权值,对于每次操作输出修改之 ...

  9. BZOJ 3295 动态逆序对 | CDQ分治

    BZOJ 3295 动态逆序对 这道题和三维偏序很类似.某个元素加入后产生的贡献 = time更小.pos更小.val更大的元素个数 + time更小.pos更大.val更小的元素个数. 分别用类似C ...

随机推荐

  1. Vue中动态(import 、require)显示img图片

    vue中,经常会遇到显示图片的问题, 如果是一个普通组件的话,那么这样就可以了 <img src="../assets/images/avtor.jpg" width=&qu ...

  2. Python中的inf与nan

    Python中可以用如下方式表示正负无穷 >>> float('inf') # 正无穷,inf不区分大小写,float('InF')一样可以. inf >>> fl ...

  3. Maven从入门到放弃

    1.maven是什么? maven是Apache下的一个纯java开发的一个开源项目,它是一款能够抽象构建过程,并且提供依赖管理,中央仓库,自动下载构建等功能的项目构建工具. 2.为什么要使用mave ...

  4. Nginx + Lua 搭建网站WAF防火墙

    前言 对于项目里面只是使用代理等常用功能,在线安装即可,如需制定化模块,则推荐编译安装 PS:本文不仅仅包含Nginx相关的知识点,还包含了逆天学习方法(对待新事物的处理) 官方网站:https:// ...

  5. java高并发系列 - 第22天:java中底层工具类Unsafe,高手必须要了解

    这是java高并发系列第22篇文章,文章基于jdk1.8环境. 本文主要内容 基本介绍. 通过反射获取Unsafe实例 Unsafe中的CAS操作 Unsafe中原子操作相关方法介绍 Unsafe中线 ...

  6. SQL和NoSQL的区别

    一.概念 SQL (Structured Query Language) 数据库,指关系型数据库.主要代表:SQL Server,Oracle,MySQL(开源),PostgreSQL(开源). No ...

  7. cogs 1254. 最难的任务 Dijkstra + 重边处理

    1254. 最难的任务 ★   输入文件:hardest.in   输出文件:hardest.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述] 这个真的很难.算出 123 ...

  8. Vue系列:Websocket 使用配置

    WebSocket 是什么? WebSocket  是一种网络通信协议.而且是在 HTML5 才开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. 为什么需要 WebSocket ? 了解计算 ...

  9. 使用 RxJava 进行嵌套串行网络请求的一种方法

    需求 有这样一个列表数据,它包含了商店+订单的信息,获取订单列表时,订单实体中会包含商店的 ID,而列表显示时需要商店的名称和 logo,这时候就需要进行嵌套串行网络请求了. 关键词 flatMap ...

  10. MTFlexbox自动化埋点探索

    1. 背景 跨平台动态化技术是目前移动互联网领域的重点关注方向,它既能节约人力,又能实现业务快速上线的需求.经过十年的发展,美团App已经变成了一个承载众多业务的超级平台,众多的业务方对业务形态的快速 ...