【BZOJ1455】罗马游戏 可并堆
2015-03-21 09:36
225 查看
链接:
#include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44513511"); }
题解:
可并堆:其实它只是个函数,而不是数据结构,它的数据结构只是“堆”?
可并的随机堆才算一个?
两个堆合并时,对比大小决定谁是父亲,然后劣的和优的 的子再递归进行比较,直到一头为空(无法也不用再比较时),能满足正常插入就可以保证二叉的性质时停止。
代码:
可并随机堆(随机挂到某子上)#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 1001000 #define inf 0x3f3f3f3f using namespace std; struct Merge_Heap { int son [2],val ; bool be_killed ; int fa ; int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} void init(int n) { val[0]=inf; for(int i=1;i<=n;i++) { scanf("%d",&val[i]); fa[i]=i; } } int merge(int x,int y) // 小根随机可并堆 { if(val[x]>val[y])swap(x,y); if((x&&y)==0)return x; int k=rand()&1; son[x][k]=merge(son[x][k],y); return x; } void kill() { int x; scanf("%d",&x); if(be_killed[x]) { puts("0"); return ; } x=find(x); be_killed[x]=1; printf("%d\n",val[x]); int k=merge(son[x][0],son[x][1]); if(k)fa[x]=fa[son[x][0]]=fa[son[x][1]]=k; } void battle() { int x,y; scanf("%d%d",&x,&y); if(be_killed[x]||be_killed[y])return ; if(find(x)==find(y))return ; fa[fa[x]]=fa[fa[y]]=merge(fa[x],fa[y]); } }heap; int n,m; char opt[5]; int main() { // freopen("test.in","r",stdin); srand(252503); int i,k; scanf("%d",&n); heap.init(n); for(scanf("%d",&m);m--;) { scanf("%s",opt); if(opt[0]=='K')heap.kill(); else heap.battle(); } return 0; }
相关文章推荐
- [BZOJ1455]罗马游戏 左偏树+并查集
- BZOJ-1455 罗马游戏
- 【bzoj1455】罗马游戏
- BZOJ 1455 罗马游戏 左偏树
- 【BZOJ1455】罗马游戏
- [bzoj1455]罗马游戏 左偏树
- BZOJ 1455 罗马游戏
- BZOJ1455 罗马游戏
- BZOJ 1455 罗马游戏 [右偏树(误)][左偏树]
- [BZOJ1455]罗马游戏(可并堆)
- 【bzoj1455】罗马游戏 可并堆
- bzoj1455 罗马游戏 左偏树
- Bzoj1455 罗马游戏
- bzoj 1455 罗马游戏
- BZOJ 1455 罗马游戏
- bzoj1455: 罗马游戏
- bzoj1455 罗马游戏
- bzoj1455 罗马游戏(可并堆模板)
- bzoj 1455 罗马游戏 解题报告
- 【BZOJ-1455】罗马游戏 可并堆 (左偏树)