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;
}

猜你喜欢

转载自www.cnblogs.com/Emcikem/p/12912736.html