题意是询问一个动态序列的最小值和最大值。
可以用multiset来实现。
#include <stdio.h> #include <set> using namespace std; int main() { freopen("h.in", "r", stdin); freopen("h.ans", "w", stdout); int n; while (scanf("%d", &n) && n) { multiset<int> bills; int sum = 0; for (int i = 0; i < n; i++) { int cnt; scanf("%d", &cnt); for (int j = 0; j < cnt; j++) { int t; scanf("%d", &t); bills.insert(t); } sum += (*bills.rbegin() - *bills.begin()); bills.erase(bills.begin()); bills.erase(--bills.rbegin().base()); } printf("%d ", sum); } }
这里给出一个最小堆的做法,通过维护一个最小堆,一个最大堆,当push元素时,将这两个元素连接到一起。当pop最大或者最小的元素时,对应删除另一个堆中对应的元素。
#include <stdio.h> #include <algorithm> #include <iostream> using namespace std; const int MAXN = 1e6 + 5; const int INF = 1e9; int min_heap[MAXN], max_heap[MAXN]; int min_heap_no[MAXN], max_heap_no[MAXN]; int min_heap_no_rev[MAXN], max_heap_no_rev[MAXN]; class MinHeap { protected: int count, *heap_; public: MinHeap() {} MinHeap(int *heap) : heap_(heap), count(0) {} void push(int x) { ++count; heap_[count] = x; up(count); } int top() { return heap_[1]; } void pop() { my_swap(1, count--); heapfy(1); } /*{{{ del(int i)*/ void del(int i) { heap_[i] = -INF; up(i); pop(); } /*}}}*/ virtual void my_swap(int i, int j) { swap(heap_[i], heap_[j]); } /*{{{ heapfy(int i) */ void heapfy(int i) { while (i <= count) { int smallest = i; if (2 * i <= count && heap_[2 * i] < heap_[smallest]) { smallest = 2 * i; } if (2 * i + 1 <= count && heap_[2 * i + 1] < heap_[smallest]) { smallest = 2 * i + 1; } if (i != smallest) { my_swap(i, smallest); i = smallest; } else { break; } } } /*}}}*/ /*{{{ up(int i) */ void up(int i) { while (i > 1) { if (heap_[i] < heap_[i / 2]) { my_swap(i, i / 2); i /= 2; } else { break; } } } /*}}}*/ }; class MinHeapWithMap : public MinHeap { private: int id, *no_, *no_rev_; public: MinHeapWithMap() {} MinHeapWithMap(int *heap, int *no, int *no_rev) : MinHeap(heap), no_(no), no_rev_(no_rev), id(0) {} void push(int x) { no_[count + 1] = id; no_rev_[no_[count + 1]] = count + 1; id++; MinHeap::push(x); } virtual void my_swap(int i, int j) { MinHeap::my_swap(i, j); swap(no_[i], no_[j]); no_rev_[no_[i]] = i; no_rev_[no_[j]] = j; } int top_no() { return no_[1]; } int no_rev(int i) { return no_rev_[i]; } }; class Solution { private: MinHeapWithMap minHeap_, maxHeap_; public: Solution() { minHeap_ = MinHeapWithMap(min_heap, min_heap_no, min_heap_no_rev); maxHeap_ = MinHeapWithMap(max_heap, max_heap_no, max_heap_no_rev); } void push(int x) { minHeap_.push(x); maxHeap_.push(-x); } int getMaxMinDiff() { int res = -maxHeap_.top() - minHeap_.top(); minHeap_.del(minHeap_.no_rev(maxHeap_.top_no())); maxHeap_.del(maxHeap_.no_rev(minHeap_.top_no())); minHeap_.pop(); maxHeap_.pop(); return res; } }; int main() { freopen("h.in", "r", stdin); freopen("h.out", "w", stdout); int n; while ( scanf("%d", &n), n) { Solution s; int sum = 0; for (int i = 0; i < n; i++) { int k; scanf("%d", &k); for (int j = 0; j < k; j++) { int t; scanf("%d", &t); s.push(t); } sum += s.getMaxMinDiff(); } printf("%d ", sum); } }