题意:
一个长度为 n n n 的数组,初始值全部为 0 0 0
每次选择其中最长的一段全 0 0 0 连续子数组,如果多个并列最长,取最左边的那个,并标记其左右区间 L R L R LR
如果这个子数组包含的元素个数为奇数( R − L + 1 R-L+1 R−L+1为奇数),则将这一段区间最中间那个位置标记上数字
如果这个子数组包含的元素个数为偶数,则将这一段区间内中间靠左的那个位置标记上数字
数字依次标记 1 − n 1-n 1−n,最后输出这个数组。
AC代码:
const int N = 5e5 + 50;
set<int> s[N];
int a[N];
int main()
{
int t;
sd(t);
while (t--)
{
int n;
sd(n);
rep(i, 0, n)
s[i].clear();
s[n].insert(1);
int now = 0;
per(i, n, 1)
{
if (s[i].size())
{
for (auto x : s[i])
{
int l = x, r = x + i - 1, mid = (l + r) / 2;
a[mid] = ++now;
s[mid - l].insert(l), s[r - mid].insert(mid + 1);
}
}
}
rep(i, 1, n)
printf("%d%c", a[i], i == n ? '\n' : ' ');
}
return 0;
}