BZOJ 2733: [HNOI2012]永无乡
初始给定一个n个点m条边的无向图,q次操作,每次要么新增一条边,要么查询与某个点相连的所有点里点权第K小的点的编号。 查询联通分量容易想到并查集,查询第K大需要用平衡树,容易想到每个联通分量维护一棵平衡树, 每次新增加一条边对联通分量的影响就是合并两颗平衡树,为了保障复杂度正确,我们采用启发式合并,每次把小的联通分量的每个值暴力插到大的联通分量中, 简单来看,启发式合并一次,容量至少对小的联通分量来说是翻倍,再加上插入平衡树的均摊复杂度是O(logn)的,乍一看复杂度是O(nlog^2n)的 (不过camp讲课的时候说,把小的Splay的每个数值从小到大插入到大的Splay中,时间复杂度是O(nlogn)的,证明需要用到Dynamic Finger Theorem) 然后,貌似就做完了 #include<bits/stdc++.h> using namespace std; const int maxn=5e5; const int INF=0x3f3f3f3f; typedef long long ll; struct Splay { int ch[2]; int fa; int cnt,val,sz; }b[maxn+5]; int father[maxn+5]; int tot=0,root[maxn+5]; inline int newNode(int fa,int val