您的位置:首页 > 其它

bzoj1455: 罗马游戏

2015-10-17 20:28 204 查看
原文链接:http://www.cnblogs.com/3ZStarve/p/4888137.html

裸的左偏树。

RE了好久竟然是因为cin>>ch。并不知道为什么。。

http://www.lydsy.com/JudgeOnline/problem.php?id=1455

/**************************************************************
Problem: 1455
User: 1349367067
Language: C++
Result: Accepted
Time:2088 ms
Memory:24708 kb
****************************************************************/

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,m;
struct Node
{
int x,size;
Node *l,*r,*fa;
bool kill;
}nod[1000011];
bool check_dis(Node *A)
{
if (A->r==NULL) return false;
if (A->l==NULL) return true;
if (A->l->size<A->r->size)
return true;
else
return false;
}
Node *merge(Node *A,Node *B)
{
if (A==NULL) return B;
if (B==NULL) return A;
if (A->x>B->x) swap(A,B);
A->r=merge(A->r,B);
if (check_dis(A)) swap(A->l,A->r);
A->size=1;
if (A->l!=NULL)
{
A->l->fa=A;
}
if (A->r!=NULL)
{
A->size+=A->r->size;
A->r->fa=A;
}
A->fa=NULL;
return A;
}
Node *findf(Node *A)
{
if (A->fa==NULL) return A;
else return findf(A->fa);
}
Node *delet(Node *A)
{
if (A==NULL) return NULL;
A->kill=true;
if (A->l!=NULL) A->l->fa=NULL;
if (A->r!=NULL) A->r->fa=NULL;

return merge(A->l,A->r);
}
void init()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&nod[i].x);
nod[i].size=0;
nod[i].fa=NULL;
nod[i].kill=false;
}
}
void Merge()
{
int l,r;
scanf("%d%d",&l,&r);
if (nod[l].kill||nod[r].kill) return;
Node *A,*B;
A=findf(&nod[l]);
B=findf(&nod[r]);
if (A==B) return;
A=merge(A,B);A->fa=NULL;
return;
}
int Kill()
{
int k;
scanf("%d",&k);
if (nod[k].kill) return 0;
Node *A;

A=findf(&nod[k]);
k=A->x;
A=delet(A);

return k;
}
void work()
{
int m;char ch[10];
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%s",ch);
if (ch[0]=='M') Merge();
else printf("%d\n",Kill());
}
}
int main()
{
init();
work();

return 0;
}
View Code

 

转载于:https://www.cnblogs.com/3ZStarve/p/4888137.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: