BZOJ 2001

很神仙的cdq分治

先放论文的链接   顾昱洲_浅谈一类分治算法

我们考虑分治询问,用$solve(l, r)$表示询问编号在$[l, r]$时的情况,那么当$l == r$的时候,直接把询问代入跑一个最小生成树就好了。

然而问题是怎么缩小每一层分治的规模,因为每一层都用$n$个点$m$条边来算稳$T$。

那么我们可以进行两个过程:

1、Reduction

  把与当前询问有关的边权设为$inf$跑最小生成树,那么此时不被连到最小生成树中的边一定是没什么用的,直接扔掉,这一步可以缩边。

2、Contraction

  把与当前询问有关的边权设为$-inf$跑最小生成树,那么不考虑边权为$-inf$的边连成的最小生成树的若干个连通块的边和点都是可以缩到一起的,这一步可以缩点。

这样子我们把这两个操作做完之后就可以做到把问题的规模缩减的与询问区间相关了。

时间复杂度$O(nlog^2n)$。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair <int, ll> pin;const int N = 2e4 + 5;
const int M = 5e4 + 5;
const int Lg = 20;
const ll inf = 1LL << 60;int n, m, qn, ufs[N], siz[N], pos[M], sum[Lg];
ll val[M], ans[M];
pin q[M];struct Edge {int u, v, id;ll val;friend bool operator < (const Edge &x, const Edge &y) {return x.val < y.val;}} e[Lg][M], c[M], t[M];template <typename T>
inline void read(T &X) {X = 0; char ch = 0; T op = 1;for(; ch > '9' || ch < '0'; ch = getchar())if(ch == '-') op = -1;for(; ch >= '0' && ch <= '9'; ch = getchar())X = (X << 3) + (X << 1) + ch - 48;X *= op;
}inline int find(int x) {return ufs[x] == x ? x : ufs[x] = find(ufs[x]);
}inline void merge(int x, int y) {int fx = find(x), fy = find(y);if(fx == fy) return;if(siz[fx] < siz[fy]) ufs[fx] = fy, siz[fy] += siz[fx];else ufs[fy] = fx, siz[fx] += siz[fy];
}inline void clear(int tot) {for(int i = 1; i <= tot; i++) {ufs[t[i].u] = t[i].u;ufs[t[i].v] = t[i].v;siz[t[i].u] = siz[t[i].v] = 1;}
}inline void cont(int &tot, ll &nowVal) {int cnt = 0;clear(tot);sort(t + 1, t + 1 + tot);for(int i = 1; i <= tot; i++) {int u = find(t[i].u), v = find(t[i].v);if(u == v) continue;merge(u, v);c[++cnt] = t[i];}for(int i = 1; i <= cnt; i++) {ufs[c[i].u] = c[i].u;ufs[c[i].v] = c[i].v;siz[c[i].u] = siz[c[i].v] = 1;}for(int i = 1; i <= cnt; i++) {if(c[i].val == -inf) continue;int u = find(c[i].u), v = find(c[i].v);if(u == v) continue;merge(u, v);nowVal += c[i].val;    }cnt = 0;for(int i = 1; i <= tot; i++) {int u = find(t[i].u), v = find(t[i].v);if(u == v) continue;c[++cnt] = t[i];pos[t[i].id] = cnt;c[cnt].u = ufs[t[i].u];c[cnt].v = ufs[t[i].v];}for(int i = 1; i <= cnt; i++) t[i] = c[i];tot = cnt;
}void redu(int &tot) {int cnt = 0;clear(tot);sort(t + 1, t + 1 + tot);for(int i = 1; i <= tot; i++) {if(find(t[i].u) != find(t[i].v)) {merge(t[i].u, t[i].v);c[++cnt] = t[i];pos[t[i].id] = cnt;} else if(t[i].val == inf) {c[++cnt] = t[i];pos[t[i].id] = cnt;}}for(int i = 1; i <= cnt; i++) t[i] = c[i];tot = cnt;
}void solve(int l, int r, int now, ll nowVal) {int tot = sum[now];if(l == r) val[q[l].first] = q[l].second;for(int i = 1; i <= tot; i++)e[now][i].val = val[e[now][i].id];for(int i = 1; i <= tot; i++)t[i] = e[now][i], pos[e[now][i].id] = i;if(l == r) {ans[l] = nowVal;sort(t + 1, t + 1 + tot);clear(tot);for(int i = 1; i <= tot; i++) {int u = find(t[i].u), v = find(t[i].v);if(u == v) continue;merge(u, v);ans[l] += t[i].val;}return;}for(int i = l; i <= r; i++)t[pos[q[i].first]].val = -inf;cont(tot, nowVal);for(int i = l; i <= r; i++)t[pos[q[i].first]].val = inf;redu(tot);++now;for(int i = 1; i <= tot; i++)e[now][i] = t[i];sum[now] = tot;int mid = (l + r) / 2;solve(l, mid, now, nowVal);solve(mid + 1, r, now, nowVal);
}int main() {
//    freopen("1.in", "r", stdin);
    read(n), read(m), read(qn);for(int i = 1; i <= m; i++) {read(e[0][i].u), read(e[0][i].v), read(e[0][i].val);e[0][i].id = i;val[i] = e[0][i].val;}for(int i = 1; i <= qn; i++)read(q[i].first), read(q[i].second);sum[0] = m;solve(1, qn, 0, 0LL);for(int i = 1; i <= qn; i++)printf("%lld\n", ans[i]);return 0;
}

View Code

转载于:https://www.cnblogs.com/CzxingcHen/p/9866505.html

Luogu 3206 [HNOI2010]城市建设相关推荐

  1. P3206 [HNOI2010]城市建设

    P3206 [HNOI2010]城市建设 题目描述 无向图上修改边权,动态维护MSTMSTMST,求每次修改后的MST的权值和. Solution 有一个简单好想的做法--LCTLCTLCT+线段树分 ...

  2. [HNOI2010] 城市建设_动态最小生成树(Dynamic_MST)

    这个题...暴力单次修改\(O(n)\),爆炸... $ $ 不过好在可以离线做 如果可以在 分治询问 的时候把图缩小的话就可以做了 硬着头皮把这个骚东西看完了 $ $ 动态最小生成树 然后,就把它当 ...

  3. 全国首个窄带物联网实验局落户福州 助力智慧城市建设

    市政府.省经信委.华为技术有限公司.智润科技有限公司在榕签署NB-IoT(窄带物联网)项目合作备忘录,合力在福州推进完成全国首个NB-IoT实验局建设和商业化部署,建立开放实验室,共同打造福建NB-I ...

  4. 智慧城市建设中的五个误区和四大难点

    当前,随着社会的进步,信息技术与工业.农业.社会等各个方面的全面融合发展阶段.这种深度融合又直接反映在城市的快速发展上,反映在城市建设快速向智慧化道路上的进展.建设智慧城市已经成为当今世界城市发展的趋 ...

  5. 原创 | 从智慧交通、智慧安防、智能电网三大应用场景看我国智慧城市建设现状...

    在IBM发布的<智慧的城市在中国>一书中,对"智慧城市"下了这样的定义:"能够充分运用信息和通信技术手段感测.分析.整合城市运行核心系统的各项关键信息,从而对 ...

  6. 25万亿规模!中国智慧城市建设刚需在哪?

    来源:帮尼资讯 如果说当下在中国新基建中最火的名词是什么,智慧城市这四个字几乎脱口而出.而在雪亮工程已经基本结束的当下,智慧城市接过了雪亮工程的大旗,成为了对安防企业来说利润最大.保障最稳的政府类项目 ...

  7. 智慧城市建设必须认真对待的几个问题(一):IPV6作为地址的问题

    全文共计4384字,预计阅读时间9分钟 来源 | 数据观(转载请注明来源) 作者 | 陆宝华 李晋 张永红 李学良 编辑 | 蒲蒲 引言 智慧城市已经热炒几年了,目前还在升温,并且一些做国际联网应用的 ...

  8. 数字孪生智慧城市建设加速5G+产业AI的应用,全流程数据透明化及实时可控成为升级的大方向,构建智慧城市生态圈在路上!...

    本视频为深圳市副市长和IDG领导在高交会智慧城市论坛上的讲话. 来源:北京物联网智能技术应用协会  本期正文 Digital Twin数字孪生:是充分利用物理模型.传感器更新.运行历史等数据,集成多学 ...

  9. IEEE论文:城市大脑,基于互联网大脑模型的智慧城市建设

    作者:刘锋 互联网进化论作者 计算机博士 前言:基于互联网大脑模型与智慧城市建设的结合,2015年2月在csdn第一次发布文章<基于互联网大脑架构的智慧城市建设探讨>提出了城市大脑的建设方 ...

  10. 智慧城市建设:科技创业的下一个浪潮

    来源:资本实验室 随着全球城市化进程的加速,越来越多的人涌进城市,这为城市建设带来了一系列的挑战:一方面,城市需要面对大量的越来越老化的基础设施:另一方面,需要为新涌入的城市居民提供新的,充足的基础设 ...

最新文章

  1. java dom 解析xml 例子,Java DOM解析XML的幾個例子
  2. Divide by three, multiply by two CodeForces - 977D (思维排序)
  3. 解题报告——Python编程:从入门到实践_动手试一试_参考答案(第四章)
  4. 重庆计算机硬件市场主要分布地,重庆市草地资源分布现状及类型特征
  5. IDE日志分析方法pt。 1个
  6. 前端学习(2836):view和text标签
  7. Java学习之路之Hello World小程序
  8. 聊聊机器学习中的损失函数(hinge/soft/square/0-1)
  9. Android--扫一扫(识别二维码、条码)
  10. tree.js实现3D效果,官网demo
  11. ASO优化关键词覆盖、曝光原理
  12. 途牛VS去哪儿VS去啊旅游产品竞品分析报告
  13. 关于pyrit安装失败最新解决
  14. Python中面向对象封装案例——小明爱跑步、摆放家具
  15. 网易相册助手--批量上传下载好帮手
  16. React学习中的一个小实战(智能社)
  17. 一点体会:找工作这事儿
  18. 产品-Axure9(英文版),原型设计 制作下拉二级菜单
  19. 访问非法内存区和内存泄漏
  20. 北京华客服务器数据恢复中心怎么样,北京修复数据

热门文章

  1. 计算机磁盘空间分区管理,还在用Win10自带磁盘管理? 这款软件轻松管理分区!...
  2. 软件测试睡眠原理,测一测你的睡眠质量
  3. 前端面试官经验总结 | 前端面试小技巧
  4. word 页眉 页脚 页码 分页符 目录
  5. java程序员平均工资多少,详细说明
  6. 辽宁丰睿:抖音小店搭配售卖方式怎么设置?
  7. 三种浏览器刷新操作,对缓存的影响
  8. mysql索引失效的常见原因
  9. ubuntu 输入法莫名其妙变繁体
  10. 学习机器学习总体感受