\(\mathcal{Description}\)

  给定排列 \(\{a_n\}\),求字典序第 \(K\) 大的合法排列 \(\{b_n\}\)。称一个排列 \(\{p_n\}\) 合法,当且仅当依次将 \([1,m],[2,m+1],\cdots,[n-m+1,n]\) 内的 \(p\) 升序排列后,得到的排列为 \(\{a_n\}\) 相同。

  \(n\le2 \times 10^6\),\(m\le 100\),\(K\le2 \times 10^{16}\) 。

\(\mathcal{Solution}\)

  应该说是构造题吧,想到几乎所有结论却打不出分 qwq。

  显然,\(b_i\) 在 \(\{a_n\}\) 中的下标属于集合 \([\max\{1,i-m+1\},n]\),反过来,\(a_i\) 在 \(\{b_n\}\) 中对应的下标属于集合 \([1,\min\{i+m-1,n\}]\)。

  然后可以发现 \(\{a_n\}\) 中的逆序对非常特殊。有性质:

\[ (\exists j\in[1,i))(a_i<a_j) \Rightarrow b_{i+m-1}=a_i
\]

  归纳证明。考虑一对 \((i,j)\),满足 \(\max_{k\in(i,j)}\{a_k\}<a_j<a_i\),若 \(i+1=j\),显然;否则对于 \(k\in(i,j)\),已有 \(b_{k+m-1}=a_k\),不妨设 \(b_x=a_j\),则 \(x\not\in[i+m,j+m-2]\),而 \(x\in[1,\min\{j+m-1,n\}]\),又有 \(x\ge i+m\),所以 \(x=j+m-1\) 成立。

  所以可以直接确定所有存在逆序对的 \(j\) 的位置。接下来考虑 \(\{a_n\}\) 是一个单增排列的情况。

  从左往右构造 \(\{b_n\}\),我们需要求出固定 \(\{b_n\}\) 的前缀时所有合法 \(\{b_n\}\) 的方案数。不妨设固定前 \(i\) 位,对于一个没有出现的 \(a_j\),其放置方案数显然为 \(\min\{j+m-1,n\}-i\)。乘法原理就可以得到所求,最后类似多叉树求第 \(K\) 大地枚举就好,复杂度 \(\mathcal O(n^3)\)。

  由于方案数是指数增长,所以前面很多位直接从小到达钦定,再对后缀的 \(\mathcal O(\log_mn)\) 暴力构造即可。

  复杂度 \(\mathcal O(n+\log^3n)\)。

\(\mathcal{Code}\)

/* Clearink */

#include <cstdio>
#include <algorithm> typedef long long LL; inline LL rint () {
LL x = 0; char s = getchar ();
for ( ; s < '0' || '9' < s; s = getchar () );
for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
return x;
} template<typename Tp>
inline void wint ( Tp x ) {
if ( x < 0 ) putchar ( '-' ), x = ~ x + 1;
if ( 9 < x ) wint ( x / 10 );
putchar ( x % 10 ^ '0' );
} inline int min_ ( const int a, const int b ) { return a < b ? a : b; } const int MAXN = 2e6;
int n, m, a[MAXN + 5];
LL K;
int top, stk[MAXN + 5], ans[MAXN + 5];
bool used[MAXN + 5]; inline void setnxt ( int& pos, const int x ) { for ( ; ans[pos]; ++ pos ); ans[pos] = x; } int main () {
freopen ( "gift.in", "r", stdin );
freopen ( "gift.out", "w", stdout );
n = rint (), m = rint (), K = rint ();
for ( int i = 1; i <= n; ++ i ) a[i] = rint ();
for ( int i = 1; i <= n; ++ i ) {
if ( a[i] < a[stk[top]] ) ans[i + m - 1] = a[i];
else stk[++ top] = i;
}
int mut = top, pos = 1;
for ( LL all = 1; mut && all < K; -- mut ) {
all *= min_ ( m, top - mut + 2 );
}
for ( int i = 1; i < mut; ++ i ) setnxt ( pos, a[stk[i]] );
for ( int i = mut; i <= top; ++ i ) {
for ( int j = mut; j <= top; ++ j ) {
if ( used[j] ) continue;
used[j] = true;
LL all = 1;
for ( int k = mut, pre = i; k <= top; ++ k ) {
if ( !used[k] ) {
all *= min_ ( top, k + m - 1 ) - pre ++;
}
}
if ( all < K ) K -= all, used[j] = false;
else { setnxt ( pos, a[stk[j]] ); break; }
}
}
for ( int i = 1; i <= n; ++ i ) {
wint ( ans[i] );
putchar ( i ^ n ? ' ' : '\n' );
}
return 0;
}

Solution -「LOCAL」「cov. 牛客多校 2020 第三场 I」礼物的更多相关文章

  1. Solution -「LOCAL」「cov. 牛客多校 2020 第五场 C」Easy

    \(\mathcal{Description}\)   Link.(完全一致)   给定 \(n,m,k\),对于两个长度为 \(k\) 的满足 \(\left(\sum_{i=0}^ka_i=n\r ...

  2. 2019牛客多校训练第三场H.Magic Line(思维)

    题目传送门 大致题意: 输入测试用例个数T,输入点的个数n(n为偶数),再分别输入n个不同的点的坐标,要求输出四个整数x1,y1,x2,y2,表示有一条经过点(x1,y1),(x2,y2)的直线将该二 ...

  3. 2019牛客多校训练第三场B.Crazy Binary String(思维+前缀和)

    题目传送门 大致题意: 输入整数n(1<=n<=100000),再输入由n个0或1组成的字符串,求该字符串中满足1和0个数相等的最长子串.子序列. sample input: 801001 ...

  4. 牛客多校对抗第6场 A Singing Contest

    [20分]标题:A.Singing Contest | 时间限制:1秒 | 内存限制:256MJigglypuff is holding a singing contest. There are 2n ...

  5. 牛客多校训练第八场C.CDMA(思维+构造)

    题目传送门 题意: 输入整数m( m∈2k ∣ k=1,2,⋯,10),构造一个由1和-1组成的m×m矩阵,要求对于任意两个不同的行的内积为0. 题解: Code: #include<bits/ ...

  6. 牛客多校训练第八场G.Gemstones(栈模拟)

    题目传送门 题意: 输入一段字符串,字符串中连续的三个相同的字符可以消去,消去后剩下的左右两段字符串拼接,求最多可消去次数. 输入:ATCCCTTG   输出:2 ATCCCTTG(消去CCC)——& ...

  7. 2019牛客多校训练第四场K.number(思维)

    题目传送门 题意: 输入一个只包含数字的字符串,求出是300的倍数的子串的个数(不同位置的0.00.000等都算,并考虑前导零的情况). sample input: 600 1230003210132 ...

  8. 2019暑假牛客多校训练-第八场-C-CDMA(递归、水题)

    观察前3组可以推出递归规律,生成下一个类型时,每行copy自身与自身相反. 题目描述 Gromah and LZR have entered the third level. There is a b ...

  9. 2018年牛客多校寒假 第四场 F (call to your teacher) (图的连通性)

    题目链接 传送门:https://ac.nowcoder.com/acm/contest/76/F 思路: 题目的意思就是判断图的连通性可以用可达性矩阵来求,至于图的存储可以用邻接矩阵来储存,求出来可 ...

随机推荐

  1. Python常用功能函数系列总结(三)

    本节目录 常用函数一:词频统计 常用函数二:word2vec 常用函数三:doc2vec 常用函数四:LDA主题分析 常用函数一:词频统计 # -*- coding: utf-8 -*- " ...

  2. Hive分析统计离线日志信息

    关注公众号:分享电脑学习回复"百度云盘" 可以免费获取所有学习文档的代码(不定期更新)云盘目录说明:tools目录是安装包res 目录是每一个课件对应的代码和资源等doc 目录是一 ...

  3. 彻底剖析JVM类加载机制

    本文仍然基于JDK8版本,从JDK9模块化器,类加载器有一些变动. 0 javac编译 java代码 public class Math { public static final int initD ...

  4. 基于Dapper的分布式链路追踪入门——Opencensus+Zipkin+Jaeger

    微信搜索公众号 「程序员白泽」,进入白泽的编程知识分享星球 最近做了一些分布式链路追踪有关的东西,写篇文章来梳理一下思路,或许可以帮到想入门的同学.下面我将从原理到demo为大家一一进行讲解,欢迎评论 ...

  5. 一些Markdown扩展语法

    相信很多人跟我一样,对Markdown是"一知半解",会打一点,知道一点,但是其实从没花哪怕一分钟了解过.其实除了标题粗体插入代码,Markdown还有很多有趣的基础语法和扩展语法 ...

  6. nao机器人使用手册

    简单使用和保养 开关机和马达 开机是按一下,后来按一下相当于重启了一次程序,3是播报IP地址,5秒是关机,8秒是强制关机. 电池 3月左右不用需要取下电池.夏天5-8小时,冬天8-10小时充电.活动时 ...

  7. Cesium源码剖析---Clipping Plane

    之前就一直有写博客的想法,别人也建议写一写,但一直没有动手写,自己想了一下原因,就一个字:懒.懒.懒.为了改掉这个毛病,决定从今天开始写博客了,一方面对自己掌握的知识做一个梳理,另一方面和大家做一个交 ...

  8. Azure Terraform(十)利用 Azure DevOps 的条件语句选择发布环境

    一,引言 之前我讲过的所有的案例中,都是将整个Azure Resource 部署到同一个订阅下,没有做到灵活的在 Azure Pipeline 在运行前选择需要部署的环境.在实际的项目开发中,我们也会 ...

  9. golang中goroutine

    1. 概念 goroutine 奉行通过通信来共享内存,而不是共享内存来通信 goroutine 是由go的运行时(runtime)调度和管理的 go程序会智能的将goroutine中的任务合理的分配 ...

  10. golang中map原理剖析

    1. golang中的map有自己的一套实现原理,其核心是由hmap和bmap两个结构体实现的 2.  初始化map package main func main() { // 初始化一个可容纳10个 ...