1. 程式人生 > >【BZOJ】2733: [HNOI2012]永無鄉

【BZOJ】2733: [HNOI2012]永無鄉

void wap cstring opened 線段 排名 while nbsp push

【題意】給定n個島嶼和排名,q次操作,連接兩個島嶼或查詢島嶼所在連通塊第k小。

【算法】平衡樹(treap)||線段樹合並

對於每個連通塊維護排名樹,啟發式合並(將size較小的樹一一拆出來加入另一棵樹)。

復雜度O(n log2n)。

技術分享圖片
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<stack>
using namespace std;
const int maxn=100010;
struct tree{int l,r,rnd,sz,num,id;}t[maxn*2
]; stack<int>s; int rank[maxn],fa[maxn],root[maxn],n,m; int read(){ char c;int s=0,t=1; while(!isdigit(c=getchar()))if(c==-)t=-1; do{s=s*10+c-0;}while(isdigit(c=getchar())); return s*t; } void up(int k){t[k].sz=t[t[k].l].sz+1+t[t[k].r].sz;} void rturn(int &k){ int o=t[k].l; t[k].l
=t[o].r; t[o].r=k; up(k);up(o); k=o; } void lturn(int &k){ int o=t[k].r; t[k].r=t[o].l; t[o].l=k; up(k);up(o); k=o; } void insert(int &k,int x){ if(!k){ k=s.top();s.pop(); t[k].rnd=rand();t[k].num=rank[x]; t[k].sz=1;t[k].l=t[k].r=0;t[k].id=x;
return; } t[k].sz++; if(rank[x]<t[k].num){ insert(t[k].l,x); if(t[t[k].l].rnd<t[k].rnd)rturn(k); } else{ insert(t[k].r,x); if(t[t[k].r].rnd<t[k].rnd)lturn(k); } } int getfa(int x){return fa[x]==x?x:fa[x]=getfa(fa[x]);} void dfs(int k,int &x){ if(!k)return; s.push(k); int L=t[k].l,R=t[k].r; insert(x,t[k].id); dfs(L,x);dfs(R,x); } void merge(int x,int y){ x=getfa(x);y=getfa(y); if(x==y)return; if(t[root[x]].sz<t[root[y]].sz)swap(x,y); fa[y]=x; dfs(root[y],root[x]); } int find(int k,int x){ if(x==t[t[k].l].sz+1)return t[k].id; else if(x<t[t[k].l].sz+1)return find(t[k].l,x); else return find(t[k].r,x-t[t[k].l].sz-1); } int main(){ srand(233); n=read();m=read(); for(int i=1;i<=n;i++)rank[i]=read(); for(int i=n;i>=1;i--)s.push(i); for(int i=1;i<=n;i++)insert(root[i],i); for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=m;i++){ int x=read(),y=read(); merge(x,y); } int Q=read(); char ch[10]; for(int i=1;i<=Q;i++){ scanf("%s",ch); int x=read(),y=read(); if(ch[0]==B)merge(x,y); else{ if(t[root[getfa(x)]].sz>=y)printf("%d\n",find(root[fa[x]],y));//use root[] else printf("-1\n"); } } return 0; }
View Code

【BZOJ】2733: [HNOI2012]永無鄉