题目链接:
https://codeforces.com/contest/1353/problem/D
思路:
我们将所有待处理的子线段按照{长度,左端点序号,右端点序号}按序存储在优先队列中,然后挨个处理即可;
代码:
#include<bits/stdc++.h>
using namespace std;
struct seg {
int len, l, r;
bool operator < (const seg & s) const {
return len == s.len ? s.l < l : s.len > len;
}
};
void solve(int & n) {
priority_queue<seg> que;
que.push(seg{
n, 1, n});
vector<int> ans(n + 1);
int cnt = 1;
while(!que.empty()) {
seg s = que.top();
que.pop();
int mid = s.l + s.r;
if(mid & 1) mid = (mid - 1) >> 1;
else mid >>= 1;
ans[mid] = cnt++;
if(mid - 1 >= s.l) que.push(seg{
mid - s.l, s.l, mid - 1});
if(s.r >= mid + 1) que.push(seg{
s.r - mid, mid + 1, s.r});
}
for(int i = 1; i <= n; i++) printf("%d ", ans[i]);
putchar('\n');
}
int main() {
#ifdef MyTest
freopen("Sakura.txt", "r", stdin);
#endif
int kase;
scanf("%d", &kase);
while(kase--) {
int n;
scanf("%d", &n);
solve(n);
}
return 0;
}