P3224 [HNOI2012]永無鄉

題目鏈接:https://www.luogu.com.cn/problem/P3224

這題的平衡樹寫法
實測不開o2的情況下權值線段樹快些,開了o2後最後一個數據平衡樹更快

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
typedef long long ll;

const int NN=100100;
const int inf=0x3f3f3f3f;
ll n,m,k,x,y,z,q,W,T,N,cnt,tmp,dst,cas,val,tot,num;
string s;char ch;
int fa[NN],id[NN];
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> rb_Tree;
rb_Tree rbt[NN];

int father(int x){
    if(x==fa[x]) return x;
    return fa[x]=father(fa[x]);
}

int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>tmp;id[tmp]=i;fa[i]=i;
        rbt[i].insert(tmp);
    }
    for(int i=1;i<=m;i++){
        cin>>x>>y;
        x=father(x);y=father(y);
        if(x==y) continue;
        if(rbt[x].size()>rbt[y].size()) swap(x,y);
        //平衡樹的join功能合併的兩棵樹一棵的值域必須嚴格小於另一棵,不能用
        //迭代器遍歷,啓發式合併
        for(rb_Tree::point_iterator it=rbt[x].begin();it!=rbt[x].end();it++)
            rbt[y].insert(*it);
        rbt[x].clear();
        fa[x]=y;
    }
    int q;cin>>q;
    for(int i=1;i<=q;i++){
        cin>>ch;
        if(ch=='Q'){
            cin>>x>>k;
            int siz=rbt[father(x)].size();
            if(k>siz) {
                cout<<-1<<endl;
                continue;
            }
            int t=*(rbt[father(x)].find_by_order(k-1));
            cout<<id[t]<<endl;
        }
        else{
            cin>>x>>y;
            x=father(x);y=father(y);
            if(x==y) continue;
            if(rbt[x].size()>rbt[y].size()) swap(x,y);
            for(rb_Tree::point_iterator it=rbt[x].begin();it!=rbt[x].end();it++)
                rbt[y].insert(*it);
            rbt[x].clear();
            fa[x]=y;
        }
    }
}

發佈了16 篇原創文章 · 獲贊 7 · 訪問量 399
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章