首页 > 其他分享 >P3224[HNOI2012]永无乡

P3224[HNOI2012]永无乡

时间:2024-08-13 21:05:42浏览次数:10  
标签:连通 int 永无 HNOI2012 P3224 平衡 size 复杂度 op

P3224[HNOI2012]永无乡

(超详细!) 居然没有人写平板电视库的题解(pbds yyds)

不了解 pbds 库的可以去看 oiwiki 或者上网学习。

题目大意

给定一个无向图,询问 \(x\) 所在连通块排名第 \(y\) 的点,且带加边修改。

刚开始每个点属于一个连通块,\(m\) 条边可以看做 \(m\) 个加边的操作。

思路

很容易想到平衡树查排名,对每个连通块维护一棵平衡树,点的排名满足二叉查找树性质。加边分两种情况。加边 \((u,v)\),如果 \(u,v\) 已经属于一个连通块,那么这条边对答案没有影响,不用管他。否则它们不属于一个连通块,加入这条新边相当于合并两个连通块,我们合并两个连通块对应的平衡树即可。

但是由于这两棵平衡树的值域有交,直接合并需要一个一个插入点,复杂度是 \(O(size\log size)\) 的。考虑经典的启发式合并,把的平衡树拆了合并到的平衡树里。

时间复杂度分析(感性理解

我们花费 \(O(size\cdot \log)\) 的复杂度至少能造出一棵大小为 \(2\times size\) 的新树。因此想要卡满时间,我们总是合并大小一样的两棵棵树,因此我们总共要拆的点有 \(o(n\log n)\) 个,合并的复杂度就是 \(O(n\log^2 n)\) 了。

find_by_order(k) insert(x) 函数都是 \(O(n\log n)\) 的。

还有个函数 size() 不清楚时间复杂度(望 dalao 告知),但是为卡常可以自己记录平衡树大小。

code(附带注释)

talk is cheap,show you my code!

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>//pbds 平衡树头文件
// #define LOCAL
#define sf scanf
#define pf printf
#define rep(x,y,z) for(int x=y;x<=z;x++)
using namespace std;
using namespace __gnu_pbds;
const int N=1e5+7,Q=3e5+7;
tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> tr[N];//主要学会比较函数,其他背下来好了
int n,m,q;
char op;
int u,v;
int w[N],wx[N];// w 是排名,wx 是排名对应的点编号
int id[N];// 点对应的平衡树编号
int siz[N];// 每棵平衡树的大小
void read(){
    op=getchar();
    while(op!='Q'&&op!='B') op=getchar();
}
void merge(int u,int v){// 启发式合并
    if(u==v) return ;
    if(siz[u]<siz[v]) swap(u,v);
    auto it=tr[v].find_by_order(0);// 找到树 v 里排名第 0 即最小的数
    siz[u]+=siz[v];
    // pf("merge %d %d\n",u,v);
    rep(i,1,siz[v]){
        int x=*it;
        // pf("%d\n",x);
        id[wx[x]]=u;
        // tr[v].erase(it);// 卡个常,反正后面也不会用到树 v 所以不删也行
        tr[u].insert(x); //插入数 x
        ++it;
    }
}
int main(){
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("my.out","w",stdout);
    #endif
    sf("%d%d",&n,&m);
    rep(i,1,n) {
        sf("%d",&w[i]);
        id[i]=i;
        wx[w[i]]=i;
        tr[i].insert(w[i]);
        siz[i]=1;
    }
    rep(i,1,m){
        sf("%d%d",&u,&v);
        merge(id[u],id[v]);
    }
    sf("%d",&q);
    rep(i,1,q){
        read();
        sf("%d%d",&u,&v);
        if(op=='Q'){
            // pf("Q %d %d\n",u,v);
            u=id[u];
            // pf("%d\n",u);
            if(v>siz[u]) {
                pf("-1\n");
                continue;
            }
            v=*tr[u].find_by_order(v-1);
            // pf("%d\n",v);
            v=wx[v];
            // pf("ans\n");
            pf("%d\n",v);
        }else{
            merge(id[u],id[v]);
        }
    }
}

标签:连通,int,永无,HNOI2012,P3224,平衡,size,复杂度,op
From: https://www.cnblogs.com/liyixin0514/p/18357683

相关文章

  • [lnsyoj300/luoguP3224/HNOI2012]永无乡
    题意给定\(n\)个集合,每个集合最开始只包含数\(a_i\),然后进行\(m\)次合并操作。具体地,每次操作将数\(a_i\)所在的集合与数\(a_j\)所在的集合合并。接下来,进行\(q\)次操作,每次操作可能为合并操作与查询操作,合并操作与上述相同,查询操作为查询数\(a_x\)所在的集合中第......
  • [HNOI2012] 矿场搭建 题解
    [HNOI2012]矿场搭建前置知识:#Tarjan求点双连通分量题目大意​ 给你一张无向连通图,任意删去其中一个点,要求在删点后在每个连通块中有一个点被选择,问至少需要选择多少个点,以及选择的方案数。输入输出格式输入​ 多组数据以\(N=0\)结束​ 每组数据第一行为边的数量\(N\(N......
  • P3219 [HNOI2012] 三角形覆盖问题&P1222 三角形 题解
    严格单$\log$做法,附实现细节和代码。考虑从左往右扫描线,发现每次操作是线段上端点$-1$,插入线段,删除退化成点的线段。如果某时刻一条线段被另一条完全覆盖,那么这条线段显然不会产生贡献,可以删去。最后得到的线段一定是左端点单调递增时,右端点也单调递增,可以用set维护。当两......
  • 【题解】HNOI2012 - 集合选数
    HNOI2012-集合选数https://www.luogu.com.cn/problem/P3226不算难的非显然状压dp。首先根据限制条件建图,\((x,2x),(x,3x)\)连边,表示边上相邻两个点不能同时选,然后一组独立集就是一个可行的集合。发现画出来的图是若干个部分网格图,每个连通块最小的点都是与\(6\)互质的数......
  • 佛祖保佑 永无bug 永不宕机
    _ooOoo_o8888888o88"."88(|-_-|)O\=/O____/`---'\____.'\\||//`./\\|||:|||//\......
  • 大型网站技术架构:核心原理与案例分析—第六章:永无止境:网站的伸缩性架构
    1,网站架构的伸缩性设计一般说来,网站的伸缩性设计可分为两类,一类是根据功能进行物理分离实现伸缩;一类是单一功能通过集群实现伸缩。前者是不同的服务器部署不同的服务,提供不同的功能;后者是集群内的多台服务器部署相同的服务,提供相同的功能。1)不同功能进行物理分离实现伸缩每......
  • [HNOI2012] 集合选数
    [HNOI2012]集合选数目录题目描述输入格式输出格式样例#1样例输入#1样例输出#1提示题意概括思路历程:1.设计状态2.设计转移代码实现:题目描述《集合论与图论》这门课程有一道作业题,要求同学们求出\(\{1,2,3,4,5\}\)的所有满足以下条件的子集:若\(x\)在该子集中,则\(2......
  • BZOJ 2730: [HNOI2012]矿场搭建 tarjan割点
    2730:[HNOI2012]矿场搭建TimeLimit: 10Sec  MemoryLimit: 128MBSubmit: 2010  Solved: 935[Submit][Status][Discuss]Description煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口......
  • 佛祖保佑,永无bug
    fozu(){return["_ooOoo_","o8888888o","88\".\"88","(|-_-|)","O\\=/O",&......
  • Luogu P3224 [HNOI2012]永无乡
    [HNOI2012]永无乡题目描述永无乡包含\(n\)座岛,编号从\(1\)到\(n\),每座岛都有自己的独一无二的重要度,按照重要度可以将这\(n\)座岛排名,名次用\(1\)到\(n\)来表示。某些岛之间由巨大的桥连接,通过桥可以从一个岛到达另一个岛。如果从岛\(a\)出发经过若干座(含\(0\)......