首页 > 其他分享 >洛谷 P3224 [HNOI2012]永无乡 题解

洛谷 P3224 [HNOI2012]永无乡 题解

时间:2022-10-20 07:44:43浏览次数:62  
标签:HNOI2012 int 题解 namespace fa MAXN ls P3224

  • 查询第 \(k\) 小值想到权值线段树
  • 合并操作想到线段树合并
  • 维护连通性想到并查集
  • 并查集合并方向应与线段树合并方向一致。
  • 查询时,先求出并查集的根再在线段树上询问。
/*
 * Title: P3224 [HNOI2012]永无乡
 * Source: 洛谷
 * URL: https://www.luogu.com.cn/problem/P3224
 * Author: Steven_lzx
 * Command: -std=c++23 -Wall -fno-ms-extensions
 * Date: 2022.10.19
 */
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN=100010;
int n,m,q;
namespace UFS
{
    int fa[MAXN];
    int find(int x){return (x==fa[x]?x:fa[x]=find(fa[x]));}
}
using namespace UFS;
namespace SEGT
{
    int idx,root[MAXN],ls[MAXN<<5],rs[MAXN<<5],id[MAXN<<5],sum[MAXN<<5];
    void update(int &p,int l,int r,int k,int c)
    {
        int mid;
        if(!p)
            p=++idx;
        if(l==r)
        {
            id[p]=c;
            sum[p]++;
            return;
        }
        mid=(l+r)>>1;
        if(k<=mid)
            update(ls[p],l,mid,k,c);
        else
            update(rs[p],mid+1,r,k,c);
        sum[p]=sum[ls[p]]+sum[rs[p]];
        return;
    }
    int query(int p,int l,int r,int k)
    {
        int res,mid;
        if(sum[p]<k||!p)
            return 0;
        if(l==r)
            return id[p];
        mid=(l+r)>>1;
        if(k<=sum[ls[p]])
            res=query(ls[p],l,mid,k);
        else 
            res=query(rs[p],mid+1,r,k-sum[ls[p]]);
        return res;
    }
    void merge(int &p,int q,int l,int r)
    {
        int mid;
        if(!q)
            return;
        if(!p)
        {
            p=q;
            return;
        }
        if(l==r)
        {
            if(id[q])
            {
                id[p]=id[q];
                sum[p]+=sum[q];
            }
            return;
        }
        mid=(l+r)>>1;
        merge(ls[p],ls[q],l,mid);
        merge(rs[p],rs[q],mid+1,r);
        sum[p]=sum[ls[p]]+sum[rs[p]]; 
        return;
    }
}
using namespace SEGT;
int main()
{
    int l,r,ans;
    char s[10];
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        fa[i]=i;
        scanf("%d",&l);
        update(root[i],1,n,l,i);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&l,&r);
        l=find(l);
        r=find(r);
        fa[r]=l;
        merge(root[l],root[r],1,n);
    }
    scanf("%d",&q);
    while(q--)
    {
        scanf("%s %d %d",s,&l,&r);
        //cout<<s<<endl;
        if(s[0]=='B')
        {
            l=find(l);
            r=find(r);
            if(l==r)
                continue;
            fa[r]=l;
            merge(root[l],root[r],1,n);
        }
        else if(s[0]=='Q')
        {
            l=find(l);
            ans=query(root[l],1,n,r);
            if(!ans)
                ans=-1;
            printf("%d\n",ans);
        }
    }
    return 0;
}

标签:HNOI2012,int,题解,namespace,fa,MAXN,ls,P3224
From: https://www.cnblogs.com/2020gyk080/p/16808423.html

相关文章

  • 力扣_剑指Offer_个人题解day05
    day05剑指Offer04.二维数组中的查找题目描述:在一个n*m的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的......
  • 力扣_剑指Offer_个人题解day03
    day03剑指Offer05.替换空格题目描述:请实现一个函数,把字符串s中的每个空格替换成"%20"。示例1:输入:s="Wearehappy."输出:"We%20are%20happy."限制:0<=s的长度......
  • 力扣_剑指Offer_个人题解
    day02剑指Offer06.从尾到头打印链表题目描述:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。示例1:输入:head=[1,3,2]输出:[2,3,1]限制:0<=链......
  • P2059 [JLOI2013] 卡牌游戏 题解
    一道不错的线性dp,带了点逆推。注意到如果我们设\(f_{i,j}\)表示前\(i\)轮过后\(j\)存活的概率,那么我们需要额外记录哪些人无了,否则无法转移。考虑这样一件事:无论......
  • tinymce粘贴word图片问题解决
    ​ 项目需求可发布文章需求涉及到富文本编辑器经过查阅我选择了较为简便不需要后端支持可独立完成的tinymce框架官方文档也是相当完整虽然都是全英文但是有强大的......
  • POJ 1389. Area of Simple Polygons 题解
    关于扫描线的介绍可以去看OIWiki。但那上面的参考代码并不好,下面给出了带注释的POJ1389题代码。/**Title:AreaofSimplePolygons*Source:POJ*URL:htt......
  • asp.net core 3.1 引用的元包dll版本兼容性问题解决方案
    自从.netcore3.1出来后,大家都想立马升级到最新版本。我也是如此,微软也对​​.netcore3.1​​的官方组件不断升级,几乎每隔几天就会有部分元包可以升级。每次打开Nuget包管......
  • MySQL 错误码: 1067Invalid default value for ‘xxx‘问题解决
    声明,此文为转载内容,原作者地址为:https://blog.csdn.net/qq_38974638/article/details/1223005381.问题描述:错误码:1067Invaliddefaultvaluefor'gmt_create......
  • AcCoders 10665:【省选基础 模拟】魔兽世界终极版 题解
    一句话,大模拟,对着题意敲就完了。干就完了,奥利给!正正好好618行~//10665ProblemG:【省选基础模拟】魔兽世界终极版#include<iostream>#include<cstdio>#include......
  • UVA353 Pesky Palindromes 题解
    题目大意给定一个字符串,求其中本质不同的回文子串的个数。解题思路时间复杂度\(O(n^3\logn)\,/\,O(n^3)\)写法非常显然的思路,直接枚举每个子串,判断其是否是回文子......