zoukankan      html  css  js  c++  java
  • BZOJ 2733 线段树的合并 并查集

    思路:
    1.线段树合并(nlogn的)
    2.splay+启发式合并

    线段树合并比较好写
    我手懒

    //By SiriusRen
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=100050;
    int n,m,q,a[N],f[N],xx,yy,son[N*50][2],tr[N*50],root[N],cnt,rev[N];
    char op[10];
    int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
    void push_up(int x){tr[x]=tr[son[x][0]]+tr[son[x][1]];}
    void insert(int &x,int l,int r,int wei){
        if(!x)x=++cnt;
        if(l==r){tr[x]++;return;}
        int mid=(l+r)>>1;
        if(mid<wei)insert(son[x][1],mid+1,r,wei);
        else insert(son[x][0],l,mid,wei); 
        push_up(x);
    }
    int merge(int x,int y){
        if(!y||!x)return x^y;
        son[x][0]=merge(son[x][0],son[y][0]),
        son[x][1]=merge(son[x][1],son[y][1]);
        push_up(x);return x;
    }
    int query(int x,int l,int r,int num){
        if(l==r)return l;
        int mid=(l+r)>>1;
        if(tr[son[x][0]]>=num)return query(son[x][0],l,mid,num);
        return query(son[x][1],mid+1,r,num-tr[son[x][0]]);
    }
    void add(){
        int fx=find(xx),fy=find(yy);
        if(fx!=fy)root[fx]=merge(root[fx],root[fy]),f[fy]=fx; 
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),f[i]=i,insert(root[i],1,n,a[i]),rev[a[i]]=i;
        while(m--)scanf("%d%d",&xx,&yy),add();
        scanf("%d",&q);
        while(q--){
            scanf("%s%d%d",op,&xx,&yy);
            if(op[0]=='Q')printf("%d
    ",tr[root[find(xx)]]<yy?-1:rev[query(root[find(xx)],1,n,yy)]);
            else add();
        }
    }

    这里写图片描述

  • 相关阅读:
    gdb php
    redis启动过程
    php protobuf 安装使用2
    php protobuf 安装使用
    服务治理
    base64编码
    redis-quicklist
    redis-ziplist
    redis-zset数据结构探索
    su root 出现 su: Authentication failure
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532046.html
Copyright © 2011-2022 走看看