CF1886C Decreasing String

传送门。显然可以 O(n) 地找到 pos 所属的 si 段,所以我们只需要得到 si 即可。不难发现,删除元素的规则应该是从 1n 枚举每个元素,删除它前面“紧邻的”比他大的元素(例如对于 eadcb 中的 b 删除掉 dc)。

赛时一直在想,怎么快速找到一个元素前面这些“紧邻的”比它大的元素,但这实际上根本不需要处理——删除掉这些组成逆序对的元素,前面的元素显然就有序了!也就是说,我们在维护一个单调栈,每次入栈 si 时,弹掉栈顶那些比它大的元素,再压入 si

需要注意的是,我们弹掉栈顶的次数是有限制的,要恰好弹掉 nlen(si) 个元素。弹完这些之后,后面即使栈内元素不单调了,也不能再弹了;如果还没弹够这个数目就完事了,则按理说要继续弹掉最后加进去的元素(按照题目字典序定义 1),但在实现中,因为 pos 不会取到后面的元素,弹不弹没有太大影响。

void solve() {
    scanf("%s", s + 1);
    int n = strlen(s + 1), tot = 0, len;
    LL pos;
    scanf("%lld", &pos); // 注意!题面中故意没有给出明确数据,导致 WA on test 8
    for (len = n; len >= 1; len--) {
        if (pos - len <= 0)  break;
        pos -= len;
    }
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
        while (cnt < n - len && tot && st[tot] > s[i]) tot--, cnt++; // 还有次数->栈不为空->不单调
        st[++tot] = s[i];
    }
    putchar(st[pos]);
}
posted @   XYukari  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示