【BZOJ】【P2733】【HNOI2012】【永无乡】【题解】【启发式合并】
2014-08-23 16:21
274 查看
传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2733
水启发式合并
Code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int maxm=5e5+10;
int n,m,q;
int getint(){
int res=0;char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))res=(res<<3)+(res<<1)+ch-'0',ch=getchar();
return res;
}
int rnd(){
static int KEY=12345678;
return KEY+=KEY<<2|1;
}
struct node{
int val,key,size,s;
node *c[2];
void rz(){
size=c[0]->size+s+c[1]->size;
}
void set(int _val=0,int _key=rnd(),int _size=1,int _s=1,node *C=NULL){
val=_val;key=_key;size=_size;s=_s;c[0]=c[1]=C;
}
};
node pool[maxn];
node* newnode(){
static int tot=0;
if(tot<maxn)return &pool[tot++];
return new node();
}
struct Treap{
node *root,*Null;
Treap(){
Null=newnode();
Null->set(0,INT_MAX,0,0,Null);
root=Null;
}
void rot(node *&t,bool d){
node *p=t->c[d];t->c[d]=p->c[!d];
p->c[!d]=t;t->rz();p->rz();t=p;
}
void _insert(node *&t,int x){
if(t==Null){t=newnode();t->set(x,rnd(),1,1,Null);return;}
if(t->val==x){t->size+=1;t->s+=1;return;}
_insert(t->c[x>t->val],x);
if(t->c[x>t->val]->key<t->key)rot(t,x>t->val);
else t->rz();
}
int _kth(node *t,int x){
int r=t->c[0]->size;
if(t==Null)return 0;
else if(x<=r)return _kth(t->c[0],x);
else if(x>r+t->s)return _kth(t->c[1],x-r-t->s);
else return t->val;
}
void insert(int x){_insert(root,x);}
int kth(int x){return _kth(root,x);}
int size(){return root->size;}
}T[maxn];
int fa[maxn];
int find(int x){
if(fa[x]!=x)return fa[x]=find(fa[x]);return x;
}
void Union(int x,int y){
int fax=find(x),fay=find(y);
if(fax==fay)return;
if(T[fax].size()<T[fay].size())swap(x,y),swap(fax,fay);
fa[fay]=fax;
for(int i=0;i<T[fay].size();i++){
int val=T[fay].kth(i+1);
T[fax].insert(val);
}
}
pair<int,int> ps[maxn];
map<int,int>M;
int main(){
n=getint();m=getint();
for(int i=1;i<=n;i++){
int x=getint();
ps[i].first=x;ps[i].second=i;fa[i]=i;
}sort(ps+1,ps+1+n);
for(int i=1;i<=n;i++){
T[ps[i].second].insert(i);
M[i]=ps[i].second;
}
for(int i=1;i<=m;i++){
int u=getint(),v=getint();
Union(u,v);
}q=getint();
while(q--){
char o=getchar();
while(o!='B'&&o!='Q')o=getchar();
if(o=='B'){
int u=getint(),v=getint();
Union(u,v);
}else{
int u=find(getint()),k=getint();
if(k>T[u].size())puts("-1");
else printf("%d\n",M[T[u].kth(k)]);
}
}
return 0;
}
水启发式合并
Code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int maxm=5e5+10;
int n,m,q;
int getint(){
int res=0;char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))res=(res<<3)+(res<<1)+ch-'0',ch=getchar();
return res;
}
int rnd(){
static int KEY=12345678;
return KEY+=KEY<<2|1;
}
struct node{
int val,key,size,s;
node *c[2];
void rz(){
size=c[0]->size+s+c[1]->size;
}
void set(int _val=0,int _key=rnd(),int _size=1,int _s=1,node *C=NULL){
val=_val;key=_key;size=_size;s=_s;c[0]=c[1]=C;
}
};
node pool[maxn];
node* newnode(){
static int tot=0;
if(tot<maxn)return &pool[tot++];
return new node();
}
struct Treap{
node *root,*Null;
Treap(){
Null=newnode();
Null->set(0,INT_MAX,0,0,Null);
root=Null;
}
void rot(node *&t,bool d){
node *p=t->c[d];t->c[d]=p->c[!d];
p->c[!d]=t;t->rz();p->rz();t=p;
}
void _insert(node *&t,int x){
if(t==Null){t=newnode();t->set(x,rnd(),1,1,Null);return;}
if(t->val==x){t->size+=1;t->s+=1;return;}
_insert(t->c[x>t->val],x);
if(t->c[x>t->val]->key<t->key)rot(t,x>t->val);
else t->rz();
}
int _kth(node *t,int x){
int r=t->c[0]->size;
if(t==Null)return 0;
else if(x<=r)return _kth(t->c[0],x);
else if(x>r+t->s)return _kth(t->c[1],x-r-t->s);
else return t->val;
}
void insert(int x){_insert(root,x);}
int kth(int x){return _kth(root,x);}
int size(){return root->size;}
}T[maxn];
int fa[maxn];
int find(int x){
if(fa[x]!=x)return fa[x]=find(fa[x]);return x;
}
void Union(int x,int y){
int fax=find(x),fay=find(y);
if(fax==fay)return;
if(T[fax].size()<T[fay].size())swap(x,y),swap(fax,fay);
fa[fay]=fax;
for(int i=0;i<T[fay].size();i++){
int val=T[fay].kth(i+1);
T[fax].insert(val);
}
}
pair<int,int> ps[maxn];
map<int,int>M;
int main(){
n=getint();m=getint();
for(int i=1;i<=n;i++){
int x=getint();
ps[i].first=x;ps[i].second=i;fa[i]=i;
}sort(ps+1,ps+1+n);
for(int i=1;i<=n;i++){
T[ps[i].second].insert(i);
M[i]=ps[i].second;
}
for(int i=1;i<=m;i++){
int u=getint(),v=getint();
Union(u,v);
}q=getint();
while(q--){
char o=getchar();
while(o!='B'&&o!='Q')o=getchar();
if(o=='B'){
int u=getint(),v=getint();
Union(u,v);
}else{
int u=find(getint()),k=getint();
if(k>T[u].size())puts("-1");
else printf("%d\n",M[T[u].kth(k)]);
}
}
return 0;
}
相关文章推荐
- BZOJ 2733 [HNOI2012] 永无乡 [splay+启发式合并做法]
- 【BZOJ 2733】 [HNOI2012]永无乡|Splay启发式合并
- BZOJ 2733 HNOI 2012 永无乡 平衡树启发式合并
- [BZOJ][平衡树+启发式合并][替罪羊树]2733: [HNOI2012]永无乡
- 【BZOJ 2733】【HNOI 2012】永无乡【treap启发式合并】
- BZOJ 2733: [HNOI2012]永无乡 (Treap+启发式合并)
- BZOJ 2733: [HNOI2012]永无乡 [splay启发式合并]
- 【BZOJ 2733】[HNOI2012]永无乡 启发式合并treap
- BZOJ[2733][HNOI2012]永无乡 Splay启发式合并
- 【BZOJ 2733】【HNOI 2012】永无乡 Splay启发式合并
- BZOJ 2733: [HNOI2012]永无乡(treap + 启发式合并 + 并查集)
- bzoj 2733 [HNOI2012]永无乡 splay启发式合并
- [并查集+启发式合并]BZOJ 2733——[HNOI2012]永无乡
- bzoj 2733: [HNOI2012]永无乡(线段树启发式合并)
- BZOJ 2733([HNOI2012]永无乡-Treap启发式合并)
- BZOJ 2733: [HNOI2012]永无乡 启发式合并treap
- bzoj 2733: [HNOI2012]永无乡(线段树启发式合并)
- BZOJ 2733 HNOI2012 永无乡 Treap+启发式合并
- 【BZOJ2733】[HNOI2012]永无乡【启发式合并】【Splay】
- BZOJ1483 [HNOI2009]梦幻布丁 【链表 + 启发式合并】