bzoj2733: [HNOI2012]永无乡(并查集+主席树)

9人阅读 评论(0) 收藏 举报
分类:

题目传送门

解法:
跟3545解法差不多。
https://blog.csdn.net/hanks_o/article/details/79903342
这道题还没了边权。
直接连通。

那么并查集。
据说要启发式。
小的向大的合并。
然后就没了?

代码实现:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
struct node {int lc,rc,c;}t[2100000];int cnt,rt[110000];
void build(int &u,int l,int r,int p) {
    if(u==0)u=++cnt;t[u].c++;
    if(l==r)return ;int mid=(l+r)/2;
    if(p<=mid)build(t[u].lc,l,mid,p);
    else build(t[u].rc,mid+1,r,p);
}
void Merge(int &u1,int u2) {
    if(u1==0) {u1=u2;return ;}if(u2==0)return ;t[u1].c+=t[u2].c;
    Merge(t[u1].lc,t[u2].lc);Merge(t[u1].rc,t[u2].rc);
}
int fa[110000];int findfa(int x) {if(fa[x]!=x)fa[x]=findfa(fa[x]);return fa[x];}
int s[110000];
int find(int u,int l,int r,int k) {
    if(t[u].c==0)return -1;
    if(l==r)return s[l];int mid=(l+r)/2,c=t[t[u].lc].c;
    if(k<=c)return find(t[u].lc,l,mid,k);
    else return find(t[u].rc,mid+1,r,k-c);
}
int main() {
    int n,m;scanf("%d%d",&n,&m);cnt=0;
    for(int i=1;i<=n;i++){int x;scanf("%d",&x);build(rt[i],1,n,x);s[x]=i;}
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++) {
        int x,y;scanf("%d%d",&x,&y);
        int xx=findfa(x),yy=findfa(y);
        if(xx!=yy) {
            if(t[rt[xx]].c<=t[rt[yy]].c) {fa[xx]=yy;Merge(rt[yy],rt[xx]);}
            else {fa[yy]=xx;Merge(rt[xx],rt[yy]);}
        }
    }
    int Q;scanf("%d",&Q);
    while(Q--) {
        char s[5];int x,y;scanf("%s%d%d",s+1,&x,&y);
        if(s[1]=='Q') printf("%d\n",find(rt[findfa(x)],1,n,y));
        else {
            int xx=findfa(x),yy=findfa(y);
            if(xx!=yy) {
                if(t[rt[xx]].c<=t[rt[yy]].c) {fa[xx]=yy;Merge(rt[yy],rt[xx]);}
                else {fa[yy]=xx;Merge(rt[xx],rt[yy]);}
            }
        }
    }
    return 0;
}
查看评论

【BZOJ2733】[HNOI2012]永无乡【启发式合并】【Splay】

【题目链接】 合并时候启发式合并就可以了。 注意第9个点第99999个合并操作连接了0 0...调了好长时间= = /* Telekinetic Forest Guard */ #include...
  • BraketBN
  • BraketBN
  • 2016-05-23 07:48:31
  • 691

bzoj2733: [HNOI2012]永无乡

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 思路:splay裸题,没啥好说的...用来练练手 #include #includ...
  • thy_asdf
  • thy_asdf
  • 2015-12-30 14:11:33
  • 846

[bzoj2733][HNOI2012]永无乡

题目大意有n个点,初始时有一些边。 每次操作要么加一条边,要么询问一个点所在联通块数值第k大的点。水题联通情况并查集维护,每个连通块再对应一个权值线段树。 合并连通块就是线段树合并。#includ...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2016-06-26 10:23:14
  • 704

BZOJ2733 [HNOI2012]永无乡 平衡树启发式合并

首先因为题目中涉及到查询第K小值,所以用平衡树来维护每个连通分支
  • KuribohG
  • KuribohG
  • 2014-05-31 20:30:46
  • 1406

2733: [HNOI2012]永无乡

传说中的启发式合并,就是选出n1logn2和n2logn1中的较小值(不要跟我提常数谢谢) 用平衡树维护一个联通块,我选的SBT(好高端的样子,煞笔树吗?),然后就是俩操作了:合并两棵树,查询一棵树...
  • nlj1999
  • nlj1999
  • 2015-12-17 11:13:32
  • 413

bzoj 2733 永无乡 Treap+并查集

E - 永无乡 Time Limit:10000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Descriptio...
  • Cabinfever
  • Cabinfever
  • 2016-07-27 15:20:47
  • 706

bzoj2733【hnoi2012】永无乡

Treap+启发式合并+并查集
  • AaronGZK
  • AaronGZK
  • 2015-11-24 17:48:18
  • 1210

bzoj2733 永无乡 线段树合并

这道题是一道经典的平衡树+启发式合并吧。那么考虑用可持久化线段树来写。        对每一个节点保存一棵线段树表示所在块的编号的集合(因此可以一个块值保存一棵树),然后合并的时候就地柜合并左子节点和...
  • lych_cys
  • lych_cys
  • 2016-03-10 21:32:27
  • 1440

【bzoj2733】【HNOI2012】【永无乡】【treap+启发式合并】

Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示。某些岛之间由巨大的桥连接,通过...
  • sunshinezff
  • sunshinezff
  • 2016-03-11 09:26:49
  • 360
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 2452
    排名: 1万+
    博客专栏
    最新评论