D. Constructing the Array(排序&递归)
思路:因为只分成了 个区间,对于分区间我们可以用递归实现,然后根据题目要求进行排序即可,因此我们可以用 来储存区间长度和当前的中点下标。
对于排序方式,我们可以用将区间长度取相反数然后从小到大排,或者自己写一个自定义排序。
时间复杂度:
#include <bits/stdc++.h>
using namespace std;
const int N=2e6+5;
pair<int, int> a[N];
int b[N];
void fun(int l,int r){
if(l>r) return;
int m=(l+r)>>1;
a[m].first=l-r;//因为pair默认按first升序排,所以存入l-r 让区间长度最大的在前面
a[m].second=m;//当first相等,就按second排
fun(l,m-1);
fun(m+1,r);
}
int main()
{
int t, n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
fun(1,n);
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) b[a[i].second]=i;
for(int i=1;i<=n;i++) printf("%d ",b[i]);
puts("");
}
return 0;
}
官方解法 :
自定义排序
AC代码:
#include <bits/stdc++.h>
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;
cin >> t;
while (t--) {
int n;
cin >> n;
set<pair<int, int>, cmp> segs;
segs.insert({0, n - 1});
vector<int> a(n);
for (int i = 1; i <= n; ++i) {
pair<int, int> cur = *segs.begin();
segs.erase(segs.begin());
int id = (cur.first + cur.second) / 2;
a[id] = i;
if (cur.first < id) segs.insert({cur.first, id - 1});
if (id < cur.second) segs.insert({id + 1, cur.second});
}
for (auto it : a) cout << it << " ";
cout << endl;
}
return 0;
}