标签:
题目链接:点击打开链接
思路:
该题的关键是怎么把两个栈合并, 我们可以使用一种叫左偏树的数据结构, 满足堆的性质和集合的性质,支持在O(logn)的复杂度下进行删除堆顶元素, 插入一个元素,合并两个堆。
细节参见代码:
#include <bits/stdc++.h> using namespace std; typedef pair<int, int> P; const int maxn = 152400; P v[maxn]; int tot, u, a, b, l[maxn], r[maxn], d[maxn];//id[x]表示x所在树的编号 int Merge(int x, int y) { if(!x) return y; if(!y) return x; if(v[x] < v[y]) swap(x, y); r[x] = Merge(r[x], y); if(d[l[x]] < d[r[x]]) swap(l[x], r[x]); d[x] = d[r[x]] + 1; return x; } int init(P x) { tot++; v[tot] = x; l[tot] = r[tot] = d[tot] = 0; return tot; } int Insert(int x, P y) { return Merge(x, init(y)); } P top(int x) { return v[x]; } int pop(int x) { return Merge(l[x], r[x]); } char op[30], str[30], str2[30]; int val; int main() { int kase = 0; int N; while(scanf("%d", &N), N) { memset(v, 0, sizeof(v)); memset(l, 0, sizeof(l)); memset(r, 0, sizeof(r)); memset(d, 0, sizeof(d)); tot = u = a = b = 0; printf("Case #%d:\n", ++kase); int posA = init(P(-1, -1)); int posB = init(P(-2, -1)); for(int i = 1; i <= N; ++i) { scanf("%s%s", op, str); if(op[1] == 'u') { scanf("%d", &val); if(str[0] == 'A') { posA = Insert(posA, P(i, val)); } else { posB = Insert(posB, P(i, val)); } } else if(op[1] == 'o') { P ans; if(str[0] == 'A') { ans = top(posA); posA = pop(posA); } else { ans = top(posB); posB = pop(posB); } printf("%d\n", ans.second); } else if(op[1] == 'e') { scanf("%s", str2); if(str[0] == 'A') { posA = Merge(posA, posB); posB = init(P(-i, -1)); } else { posB = Merge(posA, posB); posA = init(P(-i, -1)); } } } } return 0; }
标签:
原文地址:http://blog.csdn.net/weizhuwyzc000/article/details/52175673