結果

問題 No.1786 Maximum Suffix Median (Online)
ユーザー 👑 NachiaNachia
提出日時 2022-02-08 18:31:50
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 258 ms / 2,000 ms
コード長 5,431 bytes
コンパイル時間 961 ms
コンパイル使用メモリ 89,864 KB
実行使用メモリ 22,828 KB
最終ジャッジ日時 2023-09-05 18:40:12
合計ジャッジ時間 9,083 ms
ジャッジサーバーID
(参考情報)
judge14 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,376 KB
testcase_01 AC 1 ms
4,376 KB
testcase_02 AC 2 ms
4,376 KB
testcase_03 AC 2 ms
4,376 KB
testcase_04 AC 2 ms
4,380 KB
testcase_05 AC 1 ms
4,376 KB
testcase_06 AC 1 ms
4,376 KB
testcase_07 AC 2 ms
4,376 KB
testcase_08 AC 122 ms
14,972 KB
testcase_09 AC 85 ms
11,304 KB
testcase_10 AC 95 ms
12,068 KB
testcase_11 AC 73 ms
10,212 KB
testcase_12 AC 134 ms
15,596 KB
testcase_13 AC 86 ms
15,000 KB
testcase_14 AC 64 ms
12,100 KB
testcase_15 AC 75 ms
13,144 KB
testcase_16 AC 81 ms
13,412 KB
testcase_17 AC 64 ms
11,764 KB
testcase_18 AC 142 ms
16,240 KB
testcase_19 AC 136 ms
16,252 KB
testcase_20 AC 136 ms
16,252 KB
testcase_21 AC 141 ms
16,388 KB
testcase_22 AC 140 ms
16,264 KB
testcase_23 AC 67 ms
18,832 KB
testcase_24 AC 49 ms
14,076 KB
testcase_25 AC 79 ms
21,048 KB
testcase_26 AC 201 ms
13,628 KB
testcase_27 AC 177 ms
12,624 KB
testcase_28 AC 218 ms
14,400 KB
testcase_29 AC 2 ms
4,376 KB
testcase_30 AC 1 ms
4,380 KB
testcase_31 AC 258 ms
16,388 KB
testcase_32 AC 78 ms
22,828 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <vector>
#include <algorithm>


namespace nachia{

    template<class Elem>
    struct leftist_heap{
        struct Node{
            Node* l;
            Node* r;
            int height;
            Elem key;
        };

        Node* root;
        int m_size;

        leftist_heap(){
            root = nullptr;
            m_size = 0;
        }

        leftist_heap(leftist_heap&& src){
            root = src.root;
            m_size = src.m_size;
            src.root = nullptr;
            src.m_size = 0;
        }

        leftist_heap& operator=(leftist_heap&& src){
            root = src.root;
            m_size = src.m_size;
            src.root = nullptr;
            src.m_size = 0;
            return *this;
        }

        ~leftist_heap(){
            if(root){
                ::std::vector<Node*> p = {root};
                while(p.size()){
                    auto c = p.back(); p.pop_back();
                    if(c->l) p.push_back(c->l);
                    if(c->r) p.push_back(c->r);
                    delete(c);
                }
            }
        }

        static Node* meld_node_norecursive(Node* root, Node* anotherroot){
            if(anotherroot == nullptr){
                return root;
            }
            if(root == nullptr){
                root = anotherroot;
                return root;
            }
            ::std::vector<Node*> st;
            st.reserve(root->height + anotherroot->height);
            Node** p1 = &root;
            Node** p2 = &anotherroot;
            while(true){
                if(*p1 == nullptr){
                    *p1 = *p2;
                    break;
                }
                if((*p1)->key < (*p2)->key) ::std::swap(*p1, *p2);
                st.push_back(*p1);
                p1 = &(*p1)->r;
            }
            auto st_ritr = st.rbegin();
            while(st_ritr != st.rend()){
                Node* c = *st_ritr;
                if(c->l == nullptr){
                    std::swap(c->l, c->r);
                    c->height = 1;
                }
                else if(c->r == nullptr){
                    c->height = 1;
                }
                else{
                    if(c->l->height < c->r->height){
                        ::std::swap(c->l, c->r);
                    }
                    c->height = c->r->height + 1;
                }
                st_ritr++;
            }
            return root;
        }

        void push(const Elem& val){
            Node* new_node = new Node();
            new_node->height = 1;
            new_node->l = nullptr;
            new_node->r = nullptr;
            new_node->key = val;
            root = meld_node_norecursive(root, new_node);
            m_size += 1;
        }

        Elem top(){
            return root->key;
        }

        void pop(){
            auto old_root = root;
            root = meld_node_norecursive(old_root->l, old_root->r);
            delete(old_root);
            m_size -= 1;
        }

        int size(){
            return m_size;
        }

        void meld(leftist_heap& r){
            root = meld_node_norecursive(root, r.root);
            r.root = nullptr;
            r.m_size = 0;
        }
    };

}



#include <algorithm>

struct less_int{
    int a;
    bool operator<(less_int& r) const { return a < r.a; }
};
struct greater_int{
    int a;
    bool operator<(greater_int& r) const { return a > r.a; }
};


struct Block{
    nachia::leftist_heap<less_int> L;
    nachia::leftist_heap<greater_int> R;
    Block() = default;
    Block(Block&& src) = default;
    Block& operator=(Block&& src) = default;
    int mid(int newitem) {
        if(L.top().a > newitem) return L.top().a;
        return newitem;
    }
    static Block make(int l, int r){
        Block res;
        res.L.push(less_int{l});
        res.R.push(greater_int{r});
        return res;
    }
};

Block merge_blocks(Block l, Block r){
    if(l.L.size() < r.L.size()) std::swap(l,r);
    l.L.meld(r.L);
    l.R.meld(r.R);
    int swap_count = 0;
    while(l.L.top().a > l.R.top().a){
        int lL = l.L.top().a; l.L.pop();
        int lR = l.R.top().a; l.R.pop();
        l.L.push(less_int{lR});
        l.R.push(greater_int{lL});
        swap_count++;
    }
    return l;
}

bool have_better_merge(Block& l, Block& r){
    return !(l.R.top().a < r.L.top().a);
}


#include <iostream>
#include <vector>

int main() {
    using namespace std;
    int N; cin >> N;
    vector<int> A(N);
    int preans = 0;

    vector<Block> blocks[2];
    for(int t=0; t<2; t++){
        blocks[t].push_back(Block::make(-2,-2));
    }

    for(int i=0; i<N; i++){
        int a; cin >> a; a ^= preans;
        A[i] = a;
        int t = i%2;
        preans = blocks[1-t].back().mid(a);
        if(i == 0){
            blocks[t].push_back(Block::make(-1,a));
        }
        else{
            Block tmp = Block::make(min(A[i-1], A[i]), max(A[i-1], A[i]));
            while(true){
                if(!have_better_merge(blocks[t].back(), tmp)) break;
                tmp = merge_blocks(move(blocks[t].back()), move(tmp));
                blocks[t].pop_back();
            }
            blocks[t].push_back(move(tmp));
        }
        cout << preans << "\n";
    }
    return 0;
}


struct ios_do_not_sync{
    ios_do_not_sync(){
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
    }
} ios_do_not_sync_instance;
0