首页 > 其他分享 >连续性区间位置查询——链式并查集

连续性区间位置查询——链式并查集

时间:2024-02-12 15:55:09浏览次数:29  
标签:ch const int 查集 long 查询 链式 区间 define

目录

问题概述

这里给出两个题目,一个是上一篇的新春漫步(其实当时给的官方题解就是链式并查集的写法,但是当时我懒得写了,emmm),二是最近vp的一场cf_div3_923场的d题,准确来说,就是因为这个我才准备写这个的,题目大概就是给出一个长度为n的数组和q组询问,每组询问会给出左区间和右区间,要求判断该区间内的数值是否一致,如果一样输出"-1 -1",否则输出一组属于该区间的不同元素的索引坐标,原题参考D. Find the Different Ones!

思路分析

首先,我们看一下这两个题的共同之处在哪里,对于"新春漫步",在上一篇随便里也写到,其实它的逻辑从出发位置找到第一个不为0的元素,其间的元素应该都是0,也就是说,是连续的;同样的,这个cf的题目,也是在一个区间内找到两个不同的元素,我们简单分析一下,对于一个位置,我们记录第一个和他不同的元素的位置,将这个位置与给出的右区间进行对比,是否就可以得出给出的区间是否是一致的的这个问题,也就是说,对于给出数组的每一个元素,我们记录向右的第一个和他不同的值即可,同样的,新春漫步也是维护这个值而已

参考代码

  • 新春漫步
#include <bits/stdc++.h>
using namespace std;
#define FAST_IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define pll pair<long long, long long>
#define pii pair<int, int>
#define vi vector<int>
#define vl vector<long long>
#define ll long long
#define ull unsigned long long
const ll INF = 9187201950435737471;
const int inf = 2139062143;
const ll mod = 1e9 + 7;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int N = 1e6+7;
int a[N];
//题目显示大量读写
inline int read() {
    //使用快读记得别关流 会tle的
    int res = 0, mark = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-') mark = -1;
        ch = getchar(); 
    }
    while(ch >= '0' && ch <= '9') {
        res = (res<<1) + (res<<3) + (ch^48);
        ch = getchar();
    }
    return res * mark;
}

inline void write(int x) {
    if(x < 0) {
        putchar('-');
        x = -x;
    }
    if(x > 9) write(x/10);
    putchar(x%10 + '0');
}
struct DSU {
    int fa[1000007];
    //并查集,支持查找、合并、计数操作(最后剩余多少集合)
    DSU(int n) {
        for(int i=1; i<=n; i++) fa[i] = i;
        fa[n+1] = 0;
    }
    int find(int x) {
        if(fa[x] == x) return x;
        return fa[x] = find(fa[x]);
    }
    void us(int x, int y) {
        fa[find(x)] = find(y);
    }
};
void solve() {
    int n, m;
    n = read(), m = read();
    DSU k(n);
    //最初每个点可以到达的最远的位置就是自己,题目给出了每个点最开始都有障碍物,如果没有的话,那么就要再多一遍由后向前的遍历
    for(int i=1; i<=n; i++) a[i] = read();
    while(m --) {
        int op, x, y;
        op = read(), x = read();
        if(op == 1) {
            y = read();
            if(a[x] > 0) {
                a[x] -= y;
                //如果当前位置的障碍物消失,那么可以到达最远的位置就是右边元素可以到达最远的位置
                //当然,作为最后一位是不需要更改的,否则就会出现fa[i] = 0的情况
                if(x < n && a[x] <= 0) k.fa[x] = k.find(x+1);
            }
        }
        else {
            write(k.find(x));
            putchar('\n');
        }
    }
}
int main() {
#ifdef xrl
    freopen("in.txt", "r", stdin), freopen("out.txt", "w", stdout);
#endif
    //FAST_IO;
    int t = 1;
    //t = read();
    while(t --) solve();
#ifdef xrl
    cout << "Time used = " << (double)(clock() * 1.0 / CLOCKS_PER_SEC) << "s";
#endif
    return 0;
}
  • Find the Different Ones!
#include <bits/stdc++.h>
using namespace std;
#define FAST_IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define pll pair<long long, long long>
#define pii pair<int, int>
#define vi vector<int>
#define vl vector<long long>
#define ll long long
#define ull unsigned long long
const ll INF = 9187201950435737471;
const int inf = 2139062143;
const ll mod = 1e9 + 7;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int N = 2e5+7;
int n, q, a[N];
struct DSU {
    int fa[200007];
    //并查集,支持查找、合并、计数操作(最后剩余多少集合)
    DSU(int n) {for(int i=1; i<=n; i++) fa[i] = i;}
    int find(int x) {
        if(fa[x] == x) return x;
        return fa[x] = find(fa[x]);
    }
    void us(int x, int y) {
        fa[find(x)] = find(y);
    }
};
void solve() {
    cin >> n;
    DSU k(n);
    for(int i=1; i<=n; i++) cin >> a[i];
    for(int i=n; i>=1; i--) {
        //这里就是上面说的由后向前初始预处理一次
        if(a[i] == a[i+1]) k.fa[i] = k.fa[i+1];
    }
    cin >> q;
    while(q --) {
        int x, y;
        cin >> x >> y;
        //如果当前点的祖先的位置超过右区间的位置,说明没有不同元素,否则,输出最近的不同的元素位置
        if(k.find(x) >= y) cout << -1 << " " << -1 << endl;
        else cout << x << " " << k.fa[x]+1 << endl;
    }
    cout << endl;
}
int main() {
#ifdef xrl
    freopen("in.txt", "r", stdin), freopen("out.txt", "w", stdout);
#endif
    FAST_IO;
    int t = 1;
    cin >> t;
    while(t --) solve();
#ifdef xrl
    cout << "Time used = " << (double)(clock() * 1.0 / CLOCKS_PER_SEC) << "s";
#endif
    return 0;
}

做题总结

区间的连续性问题,用链式并查集可以做到O(n)的时间复杂度,而且空间复杂度也不高,编码也简单,相较于线段树、树状数组等,用起来舒服很多,不过要想想明白逻辑,也满足就是连续性这个特点,这也是链的特点,假如链都不连续,怎么叫链呢

标签:ch,const,int,查集,long,查询,链式,区间,define
From: https://www.cnblogs.com/notalking569/p/18013939

相关文章

  • Service Control Manager (SCM):Windows 自带的服务控制管理器(SCM)是一个命令行工具,用于
    ServiceControlManager(SCM):Windows自带的服务控制管理器(SCM)是一个命令行工具,用于安装、启动、停止、删除和查询系统中的服务。您可以使用sc命令来执行这些操作,以及查看服务的状态和配置。描述:    SC是用来与服务控制管理器和服务进行通信    的命令行程......
  • PowerShell 命令 ,用于安装、启动、停止、删除和查询系统中的服务
    PowerShell命令,用于安装、启动、停止、删除和查询系统中的服务:安装服务:powershellCopyCodeNew-Service-Name"ServiceName"-BinaryPathName"C:\Path\to\Service.exe"这个命令将在系统中安装一个名为"ServiceName"的新服务,并指定服务的可执行文件路径为"C:\Path\to\S......
  • 第二十天:mysql查询:DML、DDL、DQL
    一、DML语句DML:INSERT,DELETE,UPDATE1、INSERT语句功能:一次插入一行或多行数据语法INSERT[LOW_PRIORITY|DELAYED|HIGH_PRIORITY][IGNORE]  [INTO]tbl_name[(col_name,...)]  {VALUES|VALUE}({expr|DEFAULT},...),(...),...  [ONDUPLIC......
  • 技术问题系列--查询过大引发的Dubbo问题
    某天上午,我喝着茶看着技术博客,突然接到一个系统告警短信,还没来得及看内容,公司的客服小姐姐就飞快的跑到面前说,“系统出问题了”,吓得我一口茶水喷了出来......1、问题反馈听了客服小姐姐的反馈之后,我又赶紧看了下系统的告警短信内容(某个微服务内存达到了阈值),紧接着我查看了系统......
  • 江西社保/医保缴费和查询
    今天陪我妈去镇上的服务中心查询她的社保(养老保险)和医保缴费记录,工作人员告诉了我们线上的查询和缴费方式,特此记录一下江西社保/医保缴费记录查询社保查询:江西人社app,选择“城乡养老账户”医保查询方式1:江西省税务局->税费服务->我要查询->社保缴费状态查询(城乡居民)(这里其实也可以......
  • 专利查询
    查询官网进入之后,参照步骤1.进入中华人民共和国国家知识产权局官网2.下滑找到“专利审查信息查询”,点击进入,选择身份登陆账号(个人查询一般是自然人)3.显示上面的界面,输入关键信息查询即可......
  • ES查询
    ES查询语句select*fromtablenameGETtablename/_search{"query":{"match_all":{}}}select*fromtablenamewheree_id="XXX"GETtablename/_search{"query":{"term":{"eId":{&quo......
  • 【查询类博客】LaTeX快查
    声明:本文非原创,部分借鉴互联网资源,著作权归原作者所有,仅供学习参考。公式插入方式行内公式$f(x)=a+b$$f(x)=a+b$行间公式$$f(x)=a+b$$$$f(x)=a+b$$手动编号$$f(x)=a-b\tag{1.1}$$$$f(x)=a-b\tag{1.1}$$空格名称语法预览说明两个......
  • PowerShell 的 Get-FileHash 命令查询一个文件的所有上述哈希值(假设是 SHA256, MD5, S
    PowerShell是一种跨平台的任务自动化解决方案,包含一个命令行外壳、脚本语言和配置管理框架。PowerShell提供了用于计算文件哈希值的内置命令Get-FileHash。Get-FileHash命令可以用来计算文件的哈希值,支持多种哈希算法。,Get-FileHash支持以下几种哈希算法:SHA256:默认算法,提......
  • powercfg是一个Windows操作系统中的命令行工具,用于管理和配置电源设置。通过使用power
    powercfg是一个Windows操作系统中的命令行工具,用于管理和配置电源设置。通过使用powercfg命令,用户和系统管理员可以查询、更改、导出、导入电源计划设置,检查电池状态,以及分析系统能耗情况等。这个工具非常有用,尤其是在需要优化电池使用时间、调整电源计划以提高性能或节能时。为......