1. 程式人生 > 實用技巧 >ACM集訓STL(1)D題

ACM集訓STL(1)D題

D - Constructing the Array

You are given an array a of length n consisting of zeros. You perform n actions with this array: during the i-th action, the following sequence of operations appears:

  1. Choose the maximum by length subarray (continuous subsegment) consisting only of zeros, among all such segments choose the leftmost one;
  2. Let this segment be $[l;r]$. If $r−l+1$ is odd (not divisible by 2) then assign (set) a[${l+r}\over{2}$]:=i (where i is the number of the current action), otherwise (if r−l+1 is even) assign (set) a[${l+r-1}\over{2}$]:=i.

Consider the array a of length 5 (initially a=$[0,0,0,0,0]$). Then it changes as follows:

  1. Firstly, we choose the segment $[1;5]$ and assign a[3]:=1, so a becomes $[0,0,1,0,0]$;
  2. then we choose the segment $[1;2]$ and assign a$[1]$:=2, so a becomes $[2,0,1,0,0]$;
  3. then we choose the segment $[4;5]$ and assign a$[4]$:=3, 4. so a becomes $[2,0,1,3,0]$;
    then we choose the segment $[2;2]$ and assign a$[2]$:=4, so 5. a becomes $[2,4,1,3,0]$;
    and at last we choose the segment $[5;5]$ and assign a$[5]$:=5, so a becomes $[2,4,1,3,5]$.
    Your task is to find the array a of length n after performing all n actions. Note that the answer exists and unique.

You have to answer t independent test cases.

Input

The first line of the input contains one integer t ($1≤t≤10^4$) — the number of test cases. Then t test cases follow.

The only line of the test case contains one integer n ($1≤n≤2⋅10^5$) — the length of a.

It is guaranteed that the sum of n over all test cases does not exceed $2⋅10^5$ ($∑n≤2⋅10 ^5$).

Output

For each test case, print the answer — the array a of length n after performing n actions described in the problem statement. Note that the answer exists and unique.

題解

#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <queue>
const int N=10000;
using namespace std;
struct segment
{
    int L;
    int R;
};
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
    struct cmp
    {
        bool operator()(segment a, segment b)
        {
            if ((a.R - a.L) != (b.R - b.L))
                return a.R - a.L < b.R - b.L;
            else return a.L > b.L;
        }
    };
    priority_queue<segment, vector<segment>, cmp> q;
    int t,j=1;
    cin >> t;
    vector<int> vec(t,0);
    segment seg;
    seg.L = 0;
    seg.R = t - 1;
    q.push(seg);
    while (!q.empty())
    {
        int L = q.top().L;
        int R = q.top().R;
        if(R-L>1)
        {
            q.pop();
            segment seg1, seg2;
            seg1.L = L;
            if ((R - L + 1) % 2 == 1)
            {
                seg1.L = L;
                seg1.R = (L + R) / 2 - 1;
                seg2.L = (L + R) / 2 + 1;
                seg2.R = R;
                vec[(L + R) / 2]=j;
            }
            else
            {
                seg1.L = L;
                seg1.R = (L + R - 1) / 2 - 1;
                seg2.L = (L + R - 1) / 2 + 1;
                seg2.R = R;
                vec[(L + R - 1) / 2]=j;
            }
            q.push(seg1);
            q.push(seg2);
        }
        else if(R-L==0){
            q.pop();
            vec[L]=j;}
            else{
                q.pop();
                segment seg1, seg2;
                seg2.L=R;
                seg2.R=R;
                vec[L]=j;
                q.push(seg2);
            }
        j++;
    }
    for(int i=0;i<t;i++){
        if(i>0)cout<<' '<<vec[i];
        else cout<<vec[i];
    }
    cout<<endl;
    }
    return 0;
}