题意

\(n\)-排列,反复进行:将序列中为前缀最大值的数全部移动到序列末(两种数不改变相对位置),问经过多少次后第一次全部升序排列

做法

定义:用high表示为前缀最大值,low则反之

考虑忽略\(1\),那么\([2,n]\)相对排好序后,假设用了\(T\)次,如果\(1\)在首,则答案为\(T\),否则还要在进行一次,为\(T+1\)

检查答案是\(T\)还是\(T + 1\)? \(T = 0\)的情况非常简单

假设\(T> 0\),并考虑\(T − 1\)运算后序列的状态

令\(f\)为在\(T-1\)运算之后,在\([2,n]\)在序列中首先出现的整数。通过\(T\)的定义,我们可以证明\(f> 2\)(否则,要么\([2,n]\)在\(T-1\)运算中排序,要么再操作一下也排不好)。可以看到,在\(T − 1\)次后,如果\(1\)出现在\(f\)和\(2\)之间,则答案为\(T\),否则为\(T + 1\)

结论1:\(f\)不会出现其不在第一个位置且为high的情况

证明:考虑反证

第一个数\(y\)为high,\(y<f\)

当它们同时为high或low,相对位置不变

否则只可能\(y=low,f=high\),相对位置还是不变

结论2

定义循环序列\((a, b, c) = (b, c, a) = (c, a, b)\)

则\(1, 2, f\)在前\(T - 1\)次组成的(关于它们位置的)循环序列不会变

证明:

\((1)\)如果\(1\)是第一个元素(这里指的不是相对顺序,就是指排在序列首)

\(~~~(i)\)如果\(2\)是第二个元素,那么\(1, 2\)是high, f是low

\(~~~(ii)\)如果\(f\)是第二个元素,那么\(1, f\)是high, 2是low

\(~~~(iii)\)否则2, f都是low

\((2)\)如果\(2\)是第一个元素,那么\(2\)是high,\(1\)和\(f\)是low

\((3)\)如果\(f\)是第一个元素,那么f是high,\(1\)和\(2\)是low

\((4)\)否则\(1, 2, f\)都是low

考虑\([i,n]\),令\(T_i\)为对序列进行排序所需的操作数。

令\(f_i\)为\(T_i − 1\)次操作后的第一个整数,考虑整数\([i,n]\)。(如果\(T_i = 0\),\(f_i\)是不确定的)。

令\(q_i\)为\(i\)在初始序列中的位置(即\(p_{q_i}= i\))。然后,我们按\(i = N,N − 1…1\)的顺序计算值\(T_i,f_i\),答案为\(T_1\)。当\(i <N\)时,可以按以下方式计算值:

  • 如果\(T_{i + 1} = 0\),

    \((1)\)如果\(q_i> q_{i + 1}\),则\(T_i = 1\),\(f_i = i + 1\)

    \((2)\)否则,\(T_i = 0\),\(f_i\)未定义。
  • 除此以外,

    \((1)\)如果\(q_{f_{i + 1}}\),\(q_i\),\(q_{i+1}\)处于此循环顺序,则\(T_i = T_{i + 1}\)和\(f_i = f_{i +1}\)。

    \((2)\)否则,\(T_i = T_{i + 1} +1\)和\(f_i = i + 1\)

题外话

题解的搬运工...

code(wxh)

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define fill( x, y ) memset( x, y, sizeof x )
#define copy( x, y ) memcpy( x, y, sizeof x )
using namespace std; typedef long long LL;
typedef pair < int, int > pa; inline int read()
{
int sc = 0, f = 1; char ch = getchar();
while( ch < '0' || ch > '9' ) { if( ch == '-' ) f = -1; ch = getchar(); }
while( ch >= '0' && ch <= '9' ) sc = sc * 10 + ch - '0', ch = getchar();
return sc * f;
} const int MAXN = 200020; int q[MAXN], p[MAXN], n, T[MAXN], f[MAXN]; int main()
{
#ifdef wxh010910
freopen( "data.in", "r", stdin );
#endif
n = read();
for( int i = 1 ; i <= n ; i++ ) q[ p[ i ] = read() ] = i;
for( int i = n - 1 ; i ; i-- )
{
if( !T[ i + 1 ] )
{
if( q[ i ] > q[ i + 1 ] ) T[ i ] = 1, f[ i ] = i + 1;
else T[ i ] = 0;
}
else
{
int cnt = 0;
cnt += q[ f[ i + 1 ] ] < q[ i ];
cnt += q[ i ] < q[ i + 1 ];
cnt += q[ i + 1 ] < q[ f[ i + 1 ] ];
if( cnt == 2 ) T[ i ] = T[ i + 1 ], f[ i ] = f[ i + 1 ];
else T[ i ] = T[ i + 1 ] + 1, f[ i ] = i + 1;
}
}
return printf( "%d\n", T[ 1 ] ), 0;
}

AGC014-F Strange Sorting的更多相关文章

  1. C Strange Sorting

    C. Strange Sorting time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  2. 数论F - Strange Way to Express Integers(不互素的的中国剩余定理)

    F - Strange Way to Express Integers Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format: ...

  3. agc014F Strange Sorting

    这套题比较简单,以为自己能够独立A掉D和E,或许就能自己A掉F,看来还真是想多了 题意:给一个$n$的全排列,每次操作把$max(a[1],a[2],...,a[i]) = a[i]$的记为$high ...

  4. 2020CCPC长春F. Strange Memory

    题目大意 一棵以 \(1\) 为根的 \(n(2\leq n\leq 10^5)\) 的树,每个节点 \(i\) 有权值 \(a_{i}(1\leq a_{i}\leq 10^6)\) ,求 \(\s ...

  5. codeforces 484C Strange Sorting Codeforces Round #276 (Div. 1) C

    思路:首先 他是对1到k 元素做一次变换,然后对2到k+1个元素做一次变化....依次做完. 如果我们对1到k个元素做完一次变换后,把整个数组循环左移一个.那么第二次还是对1 到 k个元素做和第一次一 ...

  6. 【AtCoder】AGC014

    AGC014 链接 A - Cookie Exchanges 发现两个数之间的差会逐渐缩小,所以只要不是三个数都相同,那么log次左右一定会得到答案 #include <bits/stdc++. ...

  7. Atcoder Grand-014 Writeup

    A - Cookie Exchanges 题面 Takahashi, Aoki and Snuke love cookies. They have A, B and C cookies, respec ...

  8. AtCoder Grand Contest 014

    AtCoder Grand Contest 014 A - Cookie Exchanges 有三个人,分别有\(A,B,C\)块饼干,每次每个人都会把自己的饼干分成相等的两份然后给其他两个人.当其中 ...

  9. A@GC*014

    A@GC*014 A Cookie Exchanges 卡时跑了1s就输出-1 每次操作会使三个数的极差缩小一半,所以最多\(\log\)次之后就会出现\(A=B=C\)的情况,可以直接判掉 B Un ...

随机推荐

  1. 记一次阿里云LVM扩容与 LVM 相关知识学习

    一.lvm 扩容 问题: 我们阿里云服务器有一个磁盘容量为 1T ,但是最近由于业务的扩增,磁盘容量已经不够了,需要增大磁盘的容量.磁盘挂载在 /home,使用的是 LVM.我们现在需要对磁盘进行扩容 ...

  2. 简单总结关于阿里云CDN的知识

    CDN概念剖析 这里解释一下几个概念,摘自阿里云官方文档. 源站: 源站决定了回源时,请求到哪个IP 回源host:回源host决定回源请求访问到该IP上的哪个站点 例子1:源站是域名 源站为 www ...

  3. HashMap实现详解 基于JDK1.8

    HashMap实现详解 基于JDK1.8 1.数据结构 散列表:是一种根据关键码值(Key value)而直接进行访问的数据结构.采用链地址法处理冲突. HashMap采用Node<K,V> ...

  4. 微信小程序框架分析小练手(二)——天气微信小程序制作

    简单的天气微信小程序. 一.首先,打开微信开发者工具,新建一个项目:weather.如下图: 二.进入app.json中,修改导航栏标题为“贵州天气网”. 三.进入index.wxml,进行当天天气情 ...

  5. kubernetes中node心跳处理逻辑分析

    最近在查看一个kubernetes集群中node not ready的奇怪现象,顺便阅读了一下kubernetes kube-controller-manager中管理node健康状态的组件node ...

  6. java设计模式6——代理模式

    java设计模式6--代理模式 1.代理模式介绍: 1.1.为什么要学习代理模式?因为这就是Spring Aop的底层!(SpringAop 和 SpringMvc) 1.2.代理模式的分类: 静态代 ...

  7. 《Python学习手册 第五版》 -第2章 Python如何运行程序

    第二章主要讲解了Python的运行机制, 在开始之前,需要明确以下几点 因为<Python学习手册>这本书是面向市场很多人的,既然有很多人,就有很多不一样的需求和使用情况,这本书涵盖Pyt ...

  8. 【UEFI】--- 探究BIOS NvRam空间的的位置以及大小

    按照国际惯例--先上问题:1. 什么是NvRam空间,里面存储了什么数据 2. 如何找到NvRam空间在BIOS-bin文件中的位置 NvRam空间的学名为: Non-Volatile Ram即非易失 ...

  9. Go语言实现:【剑指offer】链表中环的入口结点

    ​该题目来源于牛客网<剑指offer>专题. 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. Go语言实现: /** * Definition for sing ...

  10. Jmeter——使用JSR223元件实现RSA登录加密

    一.RSA加密简介 RSA加密是一种非对称加密.可以在不直接传递密钥的情况下,完成解密.这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险.是由一对密钥来进行加解密的过程,分别称为公钥和私 ...