CF1557B Moamen and k-subarrays 题解
阅读原文时间:2023年07月08日阅读:1

给定一个大小为 \(n\) 的数组。你可以将其分为 \(k\) 个子数组,并按照每个子数组的字典序重新排列这些子数组,再顺次拼接,得到一个新的数组。问是否存在一种划分子数组的方案,使得重新拼接后的数组是单调不降的?

数据范围:\(t\) 组数据,\(1\leqslant t\leqslant 1000\),\(1\leqslant k\leqslant n\leqslant 10^5\),\(0\leqslant |a_i|\leqslant 10^9\),\(\sum n\leqslant 3\times 10^5\)。

我们不妨将原来的数组中的元素按照其在数组中的大小顺序重新编号。例如说 \([1,-4,0,-2]\)(即样例第二组数据)可以按照这种方式重新编号为 \([4,1,3,2]\)。然后这道题目就转化为是否可以找到一组划分方案使得重新拼接后的数组是 \([1,2,3,\dots,n]\)。

这就非常简单了。首先一个很显然的结论,要想划分的数组尽量少,就尽量把变化后的数组中连续且单调递增的一段分成一个子数组。比如说 \([6,1,4,5,7,8,9,2,3]\) 就可以按照这种思想划分为 \([6],[1],[4,5],[7,8,9],[2,3]\)。可以证明这种划分方案可以使得最终划分的子数组尽量少。

设我们按照上面的方案最终划分的子数组的数量为 \(x\),则最后只需要看是否有 \(x\leqslant k\) 即可。

namespace Solution {
    int a[100007], id[100007];

    ib cmp(int ida, int idb) {return a[ida] < a[idb];}

    iv Main() {
        MT {
            int n = Rint, k = Rint, cnt = 1;
            F(int, i, 1, n) a[i] = Rint, id[i] = i;
            sort(id + 1, id + n + 1, cmp);
//            F(int, i, 1, n) printf("%d%c", id[i], " \n"[i == n]);
            F(int, i, 2, n) if(id[i] != id[i - 1] + 1) cnt++;
            cnt > k ? No : Yes;
        }
        return;
    }
}