题目传送门

题解:

对整个修改的区间进行分治。对于当前修改区间来说,我们对整幅图中将要修改的边权都先改成-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. 跟着阿里p7一起学java高并发 - 第19天:JUC中的Executor框架详解1,全面掌握java并发核心技术

    这是java高并发系列第19篇文章. 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadPoolExecutor及案例 介 ...

  2. jumpserver1.4.1 安装过程

    # 修改字符集 localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 export LC_ALL=zh_CN.UTF-8 echo 'LANG="zh_CN. ...

  3. Linux进程间通信——信号

    一.认识信号 信号(Signals)是Unix.类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式.它是一种异步的通知机制,用来提醒进程一个事件已经发生.当一个信号发送给一个进程 ...

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

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

  5. 配置多个JDK存在的问题与解决方案 (亲测可用)

    安装多个JDK时的技巧 (亲测可用) 我的电脑本来是JDK8的,后来的想在不同的JDK版本下测试JDK的垃圾回收器. 一开始的的思路是,先安装JDK,为每个JDK配置自己的家目录,然后在想用哪个版本的 ...

  6. 基于http(s)协议的模板化爬虫设计

    声明:本文为原创,转载请注明出处 本文总共三章,前面两章废话吐槽比较多,想看结果的话,直接看第三章(后续会更新,最近忙着毕设呢,毕设也是我自己做的,关于射频卡的,有时间我也放上来,哈哈). 一,系统总 ...

  7. 原 CNN--卷积神经网络从R-CNN到Faster R-CNN的理解(CIFAR10分类代码)

    1. 什么是CNN 卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Netwo ...

  8. 统计学习方法—SVM推导

    目录 SVM 1. 定义 1.1 函数间隔和几何间隔 1.2 间隔最大化 2. 线性可分SVM 2.1 对偶问题 2.2 序列最小最优算法(SMO) 3. 线性不可分SVM 3.1 松弛变量 3.2 ...

  9. 如何在GitHub上删除自己的项目?

    话不多说,直奔主题~ 1.打开GitHub,在主页左边有自己写的库. 2.拿删除第二个库wlh-hub/vue-zsgc为例,点击它,进入下面页面. 3.在导航栏一栏中,找到settings,并点击. ...

  10. bat 下 字符串拆分 类似 split 可以使用 for /f delims

    @echo offset strin=AA,BB,CC,DDfor /f "tokens=1,2,3,4 delims=, " %%a in ('echo %strin%') do ...