题目传送门

题解:

对整个修改的区间进行分治。对于当前修改区间来说,我们对整幅图中将要修改的边权都先改成-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. 19.包 logging 的使用

    包 什么是包: ---文件夹下具有__init__.py文件就是一个包 推荐使用 from . import 包的导入; from ss.bake.api.policy import func --- ...

  2. 全文检索方案Elasticsearch【Python-Django 服务端开发】

    更详细请看 https://www.elastic.co/cn/ 1. 全文检索和搜索引擎原理 商品搜索需求 当用户在搜索框输入商品关键字后,我们要为用户提供相关的商品搜索结果. 商品搜索实现 可以选 ...

  3. .NET中的值类型与引用类型

    .NET中的值类型与引用类型 这是一个常见面试题,值类型(Value Type)和引用类型(Reference Type)有什么区别?他们性能方面有什么区别? TL;DR(先看结论) 值类型 引用类型 ...

  4. MySQL Schema与数据类型优化

    Schema与数据类型优化 选择优化的数据类型 1.更小的通常更好 更小的数据类型通常更快,因为它们占用更少的磁盘,内存和CPU缓存 2.简单就好 简单数据类型的操作通常需要更少的CPU周期.例如:整 ...

  5. 作为前端的你,CC游戏开发可以上车

    1. 初来乍到 打开 Cocos Creator 点击新建空白项目,在默认布局的左下区域,一个黄黄assets文件夹映入眼帘.作为前端的你对这个文件是不是再熟悉不过了.是的,和你想象的一样,开发游戏中 ...

  6. hive数仓客户端界面工具

    1.Hive的官网上介绍了三个可以在Windows中通过JDBC连接HiveServer2的图形界面工具,包括:SQuirrel SQL Client.Oracle SQL Developer以及Db ...

  7. 微信JSSDK签名

    微信JS-SDK说明文档 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 生成签名 1.签名规则 参与签名的 ...

  8. Flink 源码解析 —— 深度解析 Flink 序列化机制

    Flink 序列化机制 https://t.zsxq.com/JaQfeMf 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac 上搭 ...

  9. 【数据结构】线段树(Segment Tree)

    假设我们现在拿到了一个非常大的数组,对于这个数组里面的数字要反复不断地做两个操作. 1.(query)随机在这个数组中选一个区间,求出这个区间所有数的和. 2.(update)不断地随机修改这个数组中 ...

  10. ubuntu16.04安装Ros(kinetic版本)【亲测好用】

    准备 1.ubuntu16.04 64位桌面版 ps:关于系统的下载和安装这里不做介绍,请自行百度,不是介绍重点 2.更改源 图上的几个勾默认是选上的,如果没有选上,选成上图这样(如果修改过勾,点击关 ...