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:
- Choose the maximum by length subarray (continuous subsegment) consisting only of zeros, among all such segments choose the leftmost one;
- 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:
- Firstly, we choose the segment $[1;5]$ and assign a[3]:=1, so a becomes $[0,0,1,0,0]$;
- then we choose the segment $[1;2]$ and assign a$[1]$:=2, so a becomes $[2,0,1,0,0]$;
- 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;
}