【离线/并查集】CF1213 G

news2024/11/20 2:30:40

想起来好久没写题解了,随便写一下把

感觉写多了div3后面的题就变得简单了,div3似乎没什么思维含量,甚至有时候能开出div3的2100....

 心血来潮写一下这个*1800的题解,思路一下就出了,但是一开始多了个log被卡了,提醒一下自己

Problem - G - Codeforces

题意:

 

思路:

首先做法肯定要给询问排序,那就相当于离线

离线的写法还是有讲究的,最好是把答案全部求出来再去O(1)查询,不然容易被卡

排序之后枚举边的权值,就是把边一条条加上去,相当于Kruskal的过程了

问题是点对的贡献怎么算,很显然可以拆,对于一个连通块,贡献为sz * (sz - 1)

那么对于每个询问是不是都要考虑遍历所有连通块,但是这样是O(nq)的

这个也是套路了,考虑询问之间的变化量,其实就是数据结构多一格的思想

如果加边之后两个连通块变成一个了,贡献的变化量是什么呢,这个可以手推

之前是 x * (x - 1) / 2,y * (y - 1) / 2

之后是 (x + y) * (x + y - 1) / 2

减一减就是 x * y

那么在合并之后贡献 += x * y即可

一开始我写成这样

#include <bits/stdc++.h>

#define int long long

constexpr int N = 2e5 + 10;
constexpr int M = 2e5 + 10;
constexpr int mod = 1e9 + 7;
constexpr int Inf = 0x3f3f3f3f;

std::pair<int, int> q[N];
std::vector<std::array<int, 2> > E[N];

int n, m;
int b[N];
int f[N], sz[N];

int find(int x) {
    return f[x] = (x == f[x]) ? x : find(f[x]);
}
void join(int u, int v) {
    int f1 = find(u), f2 = find(v);
    if (sz[f1] > sz[f2]) std::swap(f1, f2);
    if (f1 != f2) {
        f[f1] = f2;
        sz[f2] += sz[f1];
    }
}
void solve() {
    std::cin >> n >> m;
    for (int i = 1; i <= n; i ++) {
        f[i] = i;
        sz[i] = 1;
    }
    for (int i = 1; i <= n - 1; i ++) {
        int u, v, w;
        std::cin >> u >> v >> w;
        E[w].push_back({u, v});
    }
    for (int i = 1; i <= m; i ++) {
        std::cin >> q[i].first;
        q[i].second = i;
    }
    std::sort(q + 1, q + 1 + m);
    int ans = 0;
    for (int i = 1; i <= m; i ++) {
        int w = q[i].first;
        for (auto [u, v] : E[w]) {
            int f1 = find(u), f2 = find(v);
            if (f1 != f2) {
                ans += sz[f1] * sz[f2];
            }
            join(u, v);
        }
        b[q[i].second] = ans;
    }
    for (int i = 1; i <= m; i ++) {
        std::cout << b[i] << " \n" [i == m];
    }
}
signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    while(t --) {
        solve();
    }
    return 0;
}

这样子 T7了,但是枚举权值就没问题,不知道为什么这样会快,可能是STL的问题....

以后离线就写成把所有答案都求出来再去O(1)查询的形式会好一点,不容易被卡....

#include <bits/stdc++.h>

#define int long long

constexpr int N = 2e5 + 10;
constexpr int M = 2e5 + 10;
constexpr int mod = 1e9 + 7;
constexpr int Inf = 0x3f3f3f3f;

std::vector<std::array<int, 2> > E[N];

int n, m;
int b[N];
int f[N], sz[N];

int find(int x) {
    return f[x] = (x == f[x]) ? x : find(f[x]);
}
void join(int u, int v) {
    int f1 = find(u), f2 = find(v);
    if (sz[f1] > sz[f2]) std::swap(f1, f2);
    if (f1 != f2) {
        f[f1] = f2;
        sz[f2] += sz[f1];
    }
}
void solve() {
    std::cin >> n >> m;
    for (int i = 1; i <= n; i ++) {
        f[i] = i;
        sz[i] = 1;
    }
    for (int i = 1; i <= n - 1; i ++) {
        int u, v, w;
        std::cin >> u >> v >> w;
        E[w].push_back({u, v});
    }
    int ans = 0;
    for (int w = 1; w <= 2e5; w ++) {
        for (auto [u, v] : E[w]) {
            int f1 = find(u), f2 = find(v);
            if (f1 != f2) {
                ans += sz[f1] * sz[f2];
            }
            join(u, v);
        }
        b[w] = ans;
    }
    int q = 1;
    for (int i = 1; i <= m; i ++) {
        std::cin >> q;
        std::cout << b[q] << " \n" [i == m];
    }
}
signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    while(t --) {
        solve();
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1112212.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#通过Entity Framework实体对数据表增删改查

目录 一、创建实体数据模型 1.建立数据库连接 2.建立EF实体模型 二.设计窗体和EF应用 1.窗体设计 2.应用程序设计 3.源码 4.生成效果 &#xff08;1&#xff09;查询 &#xff08;2&#xff09;修改 &#xff08;3&#xff09;删除 &#xff08;4&#xff09;增加 …

Python 文件打包成可执行文件

打包 要将Python脚本打包成可执行文件&#xff0c;常见的做法是使用PyInstaller或cx_Freeze工具。下面是使用PyInstaller的基本步骤&#xff1a; 使用conda安装pyinstaller &#xff08;建议&#xff09; conda install -c conda-forge pyinstaller上面的命令从conda-forge通…

基于nodejs+vue 衣服穿搭推荐系统

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

sd卡的坏块管理与负载均衡

坏块管理 坏块是指在存储介质中出现物理损坏或不可靠的数据块。由于SD卡使用的是闪存技术&#xff0c;它也面临着坏块的问题。 SD卡通过实现坏块管理机制来处理坏块。具体的坏块管理方法可能因制造商和产品型号而有所不同&#xff0c;但通常会采取以下策略&#xff1a; 坏块标…

打卡go学习第一天

8.1 下面展示一些 代码。 package mainimport ("fmt""net""os""time" )type Clock struct {Name stringAddr string &#xff5d; func main() {clocks : []Clock{{Name: "New York", Addr: "localhost:8000"…

笔记39:在Pycharm中为项目添加新解释器

很久不用pycharm都生疏了 a a a 第一步&#xff1a;创建虚拟环境 略 a a a 第二步&#xff1a;将虚拟环境应用到项目中去 【File】----【Settings】----【Project:~~~】-----【Project Interpreter】----【选择合适的解释器】 ​​​​​​​ 因为我们要用新的解释…

【OpenCV概念】 11— 对象检测

一、说明 这都是关于物体识别的。物体识别是指通过计算机视觉技术&#xff0c;自动识别图像或视频中的物体及其属性和特征&#xff0c;是人工智能领域的一个分支。物体识别可应用于多个领域&#xff0c;包括工业自动化、智能家居、医疗、安防等。请随时阅读这篇文章&#xff1a…

摩尔信使MThings的实时数据曲线

摩尔信使MThings配备了毫秒级的实时数据录波功能&#xff0c;提供了多种展示模式&#xff0c;包括&#xff1a;固定时间范围、示波器等&#xff1b; 用户可以添加实时数据警戒线&#xff0c;直观呈现异常数据&#xff1b; 用户可以灵活的缩放、拖动曲线数据&#xff0c;可以指…

nodejs+vue衣服穿搭推荐系统-计算机毕业设计

模块包括主界面&#xff0c;系统首页、个人中心、用户管理、风格标签管理、衣服分类管理、衣服穿搭管理、服装信息管理、我的搭配管理、用户反馈、系统管理等进行相应的操作。无论是日常生活&#xff0c;还是特定场景&#xff0c;诸如面试、约会等&#xff0c;人们都有展现自我…

【试题028】C语言关于逻辑与的短路例题

1.题目&#xff1a;设inta1,b;&#xff0c;执行b0&&(a);后&#xff0c;变量a的值是&#xff1f; 2.代码解析&#xff1a; #include <stdio.h> int main() {//设inta1,b;执行b0&&(a);后&#xff0c;变量a的值是?int a 1, b;printf("表达式的值是…

【每日一题】根据规则将箱子分类

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;分类讨论 其他语言cpython3 写在最后 Tag 【分类讨论】【2023-10-20】 题目来源 2525. 根据规则将箱子分类 题目解读 题目意思明确&#xff0c;根据条件判断箱子的类别。 解题思路 方法一&#xff1a;分类讨论 根据…

Pyqt组合控件与QSpacerItem指南

Pyqt组合控件与QSpacerItem指南&#xff09; 组合控件效果如下所示&#xff1a; QSpacerItem详解 组合控件 创建一个组合的控件&#xff0c;比如 QCheckBox 和 QLabel&#xff0c;并为这个组合设置背景颜色&#xff0c;可以将它们放在一个容器小部件中&#xff0c;然后为容器小…

Leetcode——数组的旋转

189. 轮转数组 class Solution { public:void rotate(vector<int>& nums, int k) {int lennums.size();vector<int> num(len);for(int i0;i<len;i){num[(ik)%len]nums[i];}nums.assign(num.begin(),num.end());} };旋转数组 没看出数学公式gg 正确答案 cl…

经典文献阅读之--Calib Anything(使用SAM的无训练标定雷达相机外参)

0. 简介 Camera与LiDAR之间的外部标定研究正朝着更精确、更自动、更通用的方向发展&#xff0c;由于很多方法在标定中采用了深度学习&#xff0c;因此大大减少了对场景的限制。然而&#xff0c;数据驱动方法具有传输能力低的缺点。除非进行额外的训练&#xff0c;否则它无法适…

安卓Ampere Pro(充电评测)v4.09解锁专业版,供大家学习研究参考!

软件功能 支持查看充电的状态&#xff0c;充电速度是否正常&#xff0c;都可以轻松测试。 强大的测试功能&#xff0c;让你全面了解充电的状态。 温度过高提醒&#xff0c;保证手机的温度不过高&#xff0c;及时拔掉电源。 设置通知优先级&#xff0c;最高、较高、默认、较…

Zookeeper集群 + Kafka集群的详细介绍与部署

文章目录 1. Zookeeper 概述1.1 简介1.2 Zookeeper的工作机制1.3 Zookeeper 主要特点1.4 Zookeeper 数据结构1.5 Zookeeper的相关应用场景1.5.1 统一命名服务1.5.2 统一配置管理1.5.3 统一集群管理1.5.4 服务器动态上下线1.5.5 软负载均衡 1.6 Zookeeper 选举机制1.6.1 第一次启…

SI基础知识:说一说玻纤布规格(如1078)的具体含义,以及等效Dk计算

玻纤布的编织包含经向和纬向两个不同的方向&#xff0c;这些玻璃布并没有被紧密放置在一起&#xff0c;在玻纤布上会有开窗&#xff0c;而且经向开窗和纬向开窗大小不同。 IPC定义了每种玻纤布的编织密度以及所用玻璃丝的规格&#xff0c;如下图所示。 看上面的表格&#xff0c…

Fast DDS之Subscriber

目录 SubscriberSubscriberQosSubscriberListener创建Subscriber DataReaderSampleInfo读取数据 Subscriber扮演容器的角色&#xff0c;里面可以有很多DataReaders&#xff0c;它们使用Subscriber的同一份SubscriberQos配置。Subscriber可以承载不同Topic和数据类型的DataReade…

【算法学习】归并算法Merge Sort总结

归并排序思路简单&#xff0c;速度仅次于快速排序&#xff0c;为稳定排序算法&#xff0c;一般用于对总体无序&#xff0c;但是各子项相对有序的数列。 1. 基本思想 归并排序使用分治思想&#xff0c;分治模式下每一层递归有三个步骤&#xff1a; 分解&#xff08;divide)&a…

1813_ChibiOS的RT系统层

全部学习汇总&#xff1a; GreyZhang/g_ChibiOS: I found a new RTOS called ChibiOS and it seems interesting! (github.com) 在ChibiOS中有一个RT系统层的部分&#xff0c;也就是内核的系统层。这个在其他的OS中是没有看到的&#xff0c;这里针对这一部分做一个简单的认识。…