1 条题解

  • 0
    @ 2026-9-3 10:38:25

    Strange Permutation 题解

    思路

    把每个长度至少为二的翻转区间看作一个块,未被翻转的位置看作长度为一的块。因为区间互不相交,一次操作与把位置序列唯一划分成若干块等价:长度为 LL 的块倒序输出原排列的这一段,并消耗 L−1L-1 的代价。不同块划分作用在排列上会得到不同结果。

    设 F[x][r]F[x][r] 表示从位置 xx 开始、还可使用至多 rr 代价时的不同结果数,超过 4×10184\times10^{18} 的数统一截断。边界 F[n+1][r]=1F[n+1][r]=1,转移为

    F[x][r]=∑L=1r+1F[x+L][r−L+1],F[x][r]=\sum_{L=1}^{r+1}F[x+L][r-L+1],

    其中只枚举没有越过 nn 的块。暴力层直接枚举所有块划分并排序;中间层对每次询问从左到右选择块,复杂度 O(nq)O(nq)。

    做法

    满分算法注意到,在状态 (x,r)(x,r) 选择长度 LL 的块后,当前输出的第一个数是 px+L−1p_{x+L-1}。这些数互不相同,因此把至多五个候选块按该值排序,其子树在字典序中恰好连续,子树大小就是对应的 F[x+L][r−L+1]F[x+L][r-L+1]。

    真正需要加速的是连续选择长度一的块。设在状态 (x,r)(x,r) 中,排在长度一块之前的方案总数为 bxb_x。若当前名次 jj 满足

    bx<j≤bx+F[x+1][r],b_x<j\le b_x+F[x+1][r],

    就选择长度一块并令 j←j−bxj\leftarrow j-b_x。一段连续长度一转移可以用三元组 (lo,hi,sub)(lo,hi,sub) 描述:初始名次位于 (lo,hi](lo,hi] 时整段都可跳过,跳过后减去 subsub。两段拼接时将后一段的区间整体加上前段的 subsub,再求交即可。对每个剩余代价建立倍增表。

    回答询问时,用倍增跳过目标位置之前尽可能长的长度一段;一旦选择了长块,若目标位置落在块内可立即按倒序映射回答,否则消耗代价后继续。长块至多出现四次,所以单次询问复杂度 O(clog⁡n)O(c\log n)。

    复杂度

    总复杂度为 O(cnlog⁡n+cqlog⁡n)O(cn\log n+cq\log n),空间复杂度为 O(cnlog⁡n)O(cn\log n),其中 c≤4c\le4。

    • 1

    信息

    ID
    1264
    时间
    3000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者