二叉堆练题记录

1.序列合并

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 100010;

int N;
int A[maxn],B[maxn];

struct data {
    int x;
    int y;
    int val;
}h[maxn];

int read(int &x) {
    x = 0; char ch = getchar();
    while(ch < '0' || ch > '9') ch = getchar();
    while(ch >='0' && ch <='9') {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
}

#define left_child(x) ((x)*2)
#define right_child(x) ((x)*2+1)
#define father(x) ((x)/2)

int n = 0;

void swap(data & a, data & b) {
    data c = a;
    a = b;
    b = c;
}

void floatUp(int i) {
    while (father(i) > 0) {
        if (h[i].val < h[father(i)].val) {
            swap(h[i], h[father(i)]);
            i = father(i);
        } else {
            break;
        }
    }
}

void heapInsert(int x1,int y1,int value) {
    h[++ n].x = x1;
    h[n].y = y1;
    h[n].val = value;
    floatUp(n);
}

void sinkDown(int i) {
    while (left_child(i) <= n) {
        int pos = left_child(i);
        if (right_child(i) <= n && h[right_child(i)].val < h[pos].val) {
            pos = right_child(i);
        }
        if (h[i].val > h[pos].val) {
            swap(h[i], h[pos]);
            i = pos;
        } else {
            break;
        }
    }
}

void heapRemove() {
    swap(h[1], h[n]);
    -- n;
    sinkDown(1);
}


inline void init() {
    freopen("sequence.in","r",stdin);
    freopen("sequence.out","w",stdout);
    read(N);
    for (int i = 1; i <= N; ++ i) {
        read(A[i]);
    }
    for (int i = 1; i <= N; ++ i) {
        read(B[i]);
    }
}

int main() {
    init();
    for (int i = 1; i <= N; ++ i) {
        heapInsert(i,1,A[i] + B[1]);
    }
    for (int i = 1; i <= N; ++ i) {
        cout << h[1].val << " ";
        int x1 = h[1].x;
        int y1 = h[1].y + 1;
        heapRemove();
        heapInsert(x1, y1, A[x1] + B[y1]);
    }
}

猜你喜欢

转载自www.cnblogs.com/Alessandro/p/9154753.html