Codeforces 296C

写了个简单的AVL,只插入不删除。

当然Tutorial里给出的解法更简单

// Codeforces 296C
#include<iostream>
#include<cstdio>
#include<memory.h>
using namespace std;

class AVL{
private:
    struct AVLNode{
        int begin;
        int end;
        int height;
        AVLNode* left;
        AVLNode* right;

        AVLNode(int b, int e, int h = 0, AVLNode* l = NULL, AVLNode* r = NULL) :
            begin(b), end(e), height(h), left(l), right(r) {}
        AVLNode() : left(NULL), right(NULL) {}
    };

    AVLNode* root;
    int* lencnt;
    long long max;

    int Height(AVLNode* root){
        if (root == NULL) return -1;
        else return root->height;
    }

    AVLNode* LL(AVLNode* root){
        AVLNode* tmp = root->left;
        root->left = tmp->right;
        tmp->right = root;
        root->height = ((Height(root->left) > Height(root->right)) ? 
            Height(root->left) : Height(root->right)) + 1;
        tmp->height = ((Height(tmp->left) > Height(tmp->right)) ?
            Height(tmp->left) : Height(tmp->right)) + 1;
        return tmp;
    }
    AVLNode* LR(AVLNode* root){
        root->left = RR(root->left);
        root = LL(root);
        return root;
    }
    AVLNode* RL(AVLNode* root){
        root->right = LL(root->right);
        root = RR(root);
        return root;
    }
    AVLNode* RR(AVLNode* root){
        AVLNode* tmp = root->right;
        root->right = tmp->left;
        tmp->left = root;
        root->height = ((Height(root->left) > Height(root->right)) ?
            Height(root->left) : Height(root->right)) + 1;
        tmp->height = ((Height(tmp->left) > Height(tmp->right)) ?
            Height(tmp->left) : Height(tmp->right)) + 1;
        return tmp;
    }

    AVLNode* insert(AVLNode* root, int b, int e){
        if (root == NULL) return new AVLNode(b, e);

        if (e <= root->begin) root->left = insert(root->left, b, e);
        else root->right = insert(root->right, b, e);

        if (Height(root->left) - Height(root->right) >= 2){
            if (Height(root->left->left) > Height(root->left->right))
                root = LL(root);
            else root = LR(root);
        }
        else if (Height(root->right) - Height(root->left) >= 2){
            if (Height(root->right->right) > Height(root->right->left))
                root = RR(root);
            else root = RL(root);
        }

        root->height = ((Height(root->left) > Height(root->right)) ?
            Height(root->left) : Height(root->right)) + 1;

        return root;
    }

    void remove(AVLNode* root){
        if (root == NULL) return;
        remove(root->left);
        remove(root->right);
        delete root;
    }

public:
    AVL(int len){
        root = new AVLNode(0, len);
        lencnt = new int[len + 1];
        memset(lencnt, 0, (len + 1) * sizeof(int));
        lencnt[len] = 1;
        max = len;
    }

    ~AVL(){
        delete[] lencnt;
        remove(root);
    }

    void split(int pos){
        // Find the segment containing this position
        AVLNode* tmp = root;
        while (true){
            if (pos > tmp->end) tmp = tmp->right;
            else if (pos < tmp->begin) tmp = tmp->left;
            else break;
        }

        // Update the segment counts
        lencnt[tmp->end - tmp->begin]--;
        lencnt[pos - tmp->begin]++;
        lencnt[tmp->end - pos]++;
        if (lencnt[max] == 0) while (lencnt[max] == 0) max--;

        int e = tmp->end;
        tmp->end = pos;
        root = insert(root, pos, e);
    }

    long long getMax() const{
        return max;
    }

};

int main(){
    int w, h, n, i, k;
    cin >> w >> h >> n;
    AVL row(w);
    AVL col(h);
    char dir;
    int pos;

    for (k = 1; k <= n; k++){
        cin >> dir;
        if (dir == 'H'){
            cin >> pos;
            col.split(pos);
        }
        else {
            cin >> pos;
            row.split(pos);
        }

        cout << row.getMax() * col.getMax() << endl;
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值