Codeforces Round #642 (Div. 3) D. Constructing the Array - 堆的自定义排序

题目
开始全部是0,然后找到最大的区间,满足全0,然后把中间的点变成1。如果区间大小有多个,那么先操作最前面的
那么想办法把每个区间的左右范围加入,然后进行自定义排序即可
用set,然后先把\([0,n-1]\)这个区间放进set,然后找到中点标记,删除\([0,n-1]\),如果\([0,mid - 1]\)存在,那么加入set,如果\([mid + 1,n -1]\)存在,加入set
推广对于当前区间\([l,r]\),mid= (l + r) >> 1
如果\([l, mid - 1]\)存在,就加入set
如果\([mid + 1, r]\)存在,就加入set

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
using namespace std;
struct cmp{
    bool operator () (const pair<int,int> &a, const pair<int,int> &b)const{
        int lena = a.second - a.first + 1;
        int lenb = b.second - b.first + 1;
        if(lena == lenb)return a.first < b.first;
        return lena > lenb;
    }
};
int main(){
    int t;
    scanf("%d", &t);
    while(t--){
        int n;
        scanf("%d", &n);
        set<pair<int,int>, cmp> segs;
        segs.insert({0, n - 1});
        std::vector<int> a(n);
        for(int i = 1; i <= n; i++){
            pair<int,int> cur = *segs.begin();
            segs.erase(segs.begin());
            int id = (cur.second + cur.first) >> 1;
            a[id] = i;
            if(id > cur.first)segs.insert({cur.first, id - 1});
            if(id < cur.second)segs.insert({id + 1, cur.second});
        }
        for(auto x : a)cout << x << " ";
        putchar('\n');
    }
    return 0;
}
posted @ 2020-05-18 20:16  Emcikem  阅读(117)  评论(0编辑  收藏  举报