目录

P7726 天体探测仪(Astral Detector)

题目背景

通过远古档案馆的探索,你成功制出了天体探测仪,你需要用它发现潜藏的天体科技。

题目描述

想要找到天体科技,你需要先得到一串天体密码——它是一个 1n1 \sim n排列

天体探测仪允许对于给定的长度 ll,返回密码中一个长度为 ll区间的最小值

不幸的是,所有长度为 ll 的区间最小值混在了一起,你得到的只是 nn可重集合 S1,,SnS_1, \ldots , S_n

  • SiS_i 表示所有长度为 ii 的区间最小值构成的可重集合。

你需要根据这些 SiS_i,还原出一种可能的天体密码,保证至少存在一种正确的天体密码。

输入格式

第一行,一个整数 nn,表示天体密码的长度。

接下来 nn 行,其中第 ii 行包含 ni+1n - i + 1 个整数(长度为 ii 的区间共有 ni+1n - i + 1 个),表示可重集 SiS_i 中的每个元素,注意元素的顺序是任意的,而不一定是按照区间从左到右的顺序。

输出格式

输出一行 nn 个整数 p1,p2,,pnp_1, p_2, \ldots , p_n,表示你还原出的天体密码。

如有多种可行解,可以输出任意一种。

输入输出样例 #1

输入 #1

4
4 3 2 1
1 2 1
1 1
1

输出 #1

3 1 2 4

说明/提示

【样例 1 解释】

样例输出的天体密码为:p=[3,1,2,4]p = [3, 1, 2, 4]

长度为 11 的区间最小值构成的可重集合:S1={3,1,2,4}={4,3,2,1}S_1 = \{ 3, 1, 2, 4 \} = \{ 4, 3, 2, 1 \}

长度为 22 的区间最小值构成的可重集合:$S_2 = \{ \min(3, 1), \min(1, 2), \min(2, 4) \} = \{ 1, 1, 2 \} = \{ 1, 2, 1 \}$。

长度为 33 的区间最小值构成的可重集合:$S_3 = \{ \min(3, 1, 2), \min(1, 2, 4) \} = \{ 1, 1 \}$。

长度为 44 的区间最小值构成的可重集合:S4={min(3,1,2,4)}={1}S_4 = \{ \min(3, 1, 2, 4) \} = \{ 1 \}

每一个 SiS_i 都与输入对应。

其他可行答案也判为正确,如 p=[4,2,1,3]p = [4, 2, 1, 3]


【数据范围】

本题采用捆绑测试。

对于 100%100\% 的数据:2n8002 \le n \le 800

子任务编号 分值 nn \le 特殊限制
11 2626 66
22 2424 1616
33 1212 800800 对于每个 i[1,n]i \in [1, n]SiS_i 中不存在两个相同元素
44 3838
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

int n;
int cnt[805][805];
int mx_len[805];
int ans[805];

int main(){
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin >> n;
    for(int i=1; i<=n; ++i){
        for(int j=0; j<n-i+1; ++j){
            int val; cin >> val;
            cnt[val][i]++;
            mx_len[val] = max(mx_len[val], i);
        }
    }

    multiset<pair<int,int>> holes;
    holes.insert({n, 1});

    for(int v=1; v<=n; ++v){
        int len = mx_len[v];
        auto it = holes.lower_bound({len, -1});
        int size = it->first;
        int start = it->second;
        holes.erase(it);

        int pos = 0;
        for(int k=1; k<=size; ++k) pos = max(pos, cnt[v][k]);
        
        ans[start + pos - 1] = v;
        
        if(pos > 1) holes.insert({pos - 1, start});
        if(size - pos > 0) holes.insert({size - pos, start + pos});
    }

    for(int i=1; i<=n; ++i) cout << ans[i] << (i==n ? "" : " ");
    cout << "\n";
    return 0;
}

0 条评论

目前还没有评论...