Problem - 2148F - Codeforces[字符串后缀排序]

Problem - 2148F - Codeforces

题意很简单 我们可以随意防止字符串 按照从上到下 如果最后一层某个位置没有字符串 那么上面的字符串就会掉下来到最后一层 求字典序最小的最下层的字符串

首先 最朴素的思想 我们会找出当前最小长度的字符串 长度k 然后截取所有字符串的前k个前缀元素 然后排序 找到最小的一个 将整个字符串填进去 然后从k到下一个长度如此反复 但是排序和遍历过多 时间复杂度过大 这是从从左到右遍历比较后缀数字的大小

这个时候 我们可以用类似于后缀数组的倍增思想进行排序

我们从后往前遍历 用数组res 存储所有长度大于当前长度len的数组的索引

然后维护一个rk数组 表示数组的排名(按照字典序)

我们从后往前遍历 对于最后一位 直接按照最后一位的所有数组当前位置的字符进行排序

往前遍历的时候 我们可以维护一个vector<arrey<int,3>> 分别存储 {当前位置的字符 当前位置的后缀 在上一次遍历的排名 以及数组索引 }

排序完成后 第一名的就是当前位置的最优索引 然后更新一下排名 便于往前遍历的时候复用

然后进行排序 这样可以复用后缀大小的关系 直接解决包含当前位的后缀的大小的问题

最后生成答案的时候 按照每个分界位置的最优选择进行生成即可

代码如下:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
void solve(){
    int n;
    cin>>n;
    vector<vector<int>>res;
    vector<vector<int>>a(n+1);
    int maxlen=0;
    for(int i=1;i<=n;i++){
        int k;
        cin>>k;
        maxlen=max(maxlen,k);
        a[i].assign(k+1,0);
        for(int j=1;j<=k;j++){
            cin>>a[i][j];
            while(res.size()<=j)res.push_back({});
            res[j].push_back(i);
        }
    }
    vector<int>rk(n+1,-1);
    vector<int>minidx(maxlen+1,0);
    for(int i=maxlen;i>=1;i--){
        vector<array<int,3>>cur;
        for(auto j:res[i]){
            cur.push_back({a[j][i],rk[j],j});
        }
        sort(cur.begin(),cur.end());
        minidx[i]=cur[0][2];
        int rkk=0;
        for(auto j:cur){
            rk[j[2]]=++rkk;
        }
    }
    vector<int>ans;
    while(ans.size()<maxlen){
        int tmp=ans.size();
        auto &v =a[minidx[tmp+1]];
        for(int i=tmp+1;i<v.size();i++){
            ans.push_back(v[i]);
        }
    }
    for(auto x:ans)cout<<x<<' ';
    cout<<'\n';
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)solve();    
    return 0;
}
相关推荐
UIU1147 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
论文复现现场7 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
ZhengEnCi7 小时前
用 AI 写代码为什么拼到最后还是拼人:算力瓶颈与领域专家提示词的本质差异
算法·架构
秋天的怀念_David8 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
碧海银沙音频科技研究院9 小时前
在PC电脑上用Whisper→Marian算法实现离线语音翻译功能
算法·whisper
niyongsheng9 小时前
3D 装箱算法工程化:数据结构、放置启发式与支撑规则
数据结构·算法·rust
叉烧滑蛋11 小时前
B站台湾大学郭彦甫|MATLAB 学习笔记|04 变量与档案存取
数据结构
j7~12 小时前
【穷举、深搜与回溯算法】一棵决策树讲透全排列与子集
数据结构·c++·算法·leetcode·回溯·递归
傅科摆 _ py13 小时前
DP,贪心,堆和栈,二分力扣复习
开发语言·python·算法
Shaoshing13 小时前
LeetCode100 42.接雨水
java·算法·leetcode