涉及知识点:
solution:
- \(首先可以很容易想到该题的朴素做法:循环n次,每次找到最长长度的连续0子串,按照r-l+1的奇偶性进行赋值,再把分割出来的0子串加入\)
- \(很显然,朴素做法每一次操作都需要找到最长长度子串,如果每一次sort的话时间复杂度将会是 O(n*n!)\)
- \(所以,涉及到需要多次sort的题目,我们可以优先考虑优先队列\)
- \(我们只需要用pair或者结构体来存储左边界和有边界,每一次取出差值最大的那个,按照奇偶性赋值并且拆分,就可以得到我们想要的答案了\)
- \(当然比较函数需要我们自己去写,优先队列的比较函数重载可以有小于大于号重载和括号重载,这里根据自己习惯选择\)
std:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6;
int a[N];
typedef pair<int,int> PII;
struct cmp
{
bool operator()(PII a,PII b)
{
if((a.second-a.first)==(b.second-b.first))
{
return a.first > b.first;
}
else return (a.second-a.first)<(b.second-b.first);
}
};
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t -- )
{
int n;
cin >> n;
priority_queue<PII,vector<PII>,cmp> hp;
hp.push({1,n});
int ct = 0;
while(!hp.empty())
{
ct ++ ;
auto t = hp.top();
hp.pop();
int l = t.first,r = t.second;
if((r-l+1)%2 == 1)
{
if(l == r)
{
a[l] = ct;
}
else
{
int u = (l+r)/2;
a[u] = ct;
if((u-1) >= l) hp.push({l,u-1});
if((u+1) <= r) hp.push({u+1,r});
}
}
else
{
int u = (l+r-1)/2;
a[u] = ct;
if((u-1) >= l) hp.push({l,u-1});
if((u+1) <= r) hp.push({u+1,r});
}
}
for (int i = 1 ; i <= n ; i ++ )
{
cout << a[i] << " ";
}
cout << endl;
}
return 0;
}