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('
');
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Emcikem/p/12912736.html