题意

\(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. Windows下Charles从下载安装到证书设置和浏览器抓包

    1.在Charles官网https://www.charlesproxy.com/download/下载,我这边下载的是免费体验版的. 2.安装好以后打开,配置Charles证书:选择help——SS ...

  2. 事务管理(ACID)

    目录 一.事务管理(ACID) 原子性(Atomicity) 一致性(Consistency) 持久性(Durability) 隔离性(Isolation) 二.事务隔离级别 脏读 不可复读 虚读(幻 ...

  3. P4语言环境安装(一)前端编译器p4c、后端编译器p4c-bm2-ss

    这个P4安装环境是在2020-2-8安装的,安装环境卡了我好几天,把遇到的问题记录下来,有需要的同学可以参考一下,要是说错了或者有问题的话,评论或mail:guidoahead@163.com联系我都 ...

  4. Android 开启与关闭软键盘

    http://www.cnblogs.com/weixing/p/3300908.html InputMethodManager imm = (InputMethodManager)getSystem ...

  5. MPlayer参数使用介绍(部分)(中文)

    文件太长,就不全部转载了,以下是某MPlayer网站的全部详细介绍: http://www.mplayer.org.cn/help_zh.html#%E7%A8%8B%E5%BA%8F%E9%94%9 ...

  6. Request和Session的生命周期

    request的生命周期是request请求域,一个请求结束,则request结束 session的生命周期是session会话域,打开一个浏览器请求一个网站的页面后,Session开始,当sessi ...

  7. 小白学习VUE第二课:环境搭建 VUE Node.js VSCode template模板

    环境搭建 VUE Node.js VSCode template模板: 首先安装node:http://www.runoob.com/nodejs/nodejs-install-setup.html ...

  8. Codeforces 1092 F Tree with Maximum Cost (换根 + dfs)

    题意: 给你一棵无根树,每个节点有个权值$a_i$,指定一个点u,定义$\displaystyle value = \sum^v a_i*dist(u,v)$,求value的最大值 n,ai<= ...

  9. 《剑指Offer》第二章(一)题3-8

    为春招实习做准备,记录一下<剑指Offer>里面的面试题 第二章 面试题3:数组之中的重复数字. 这个题吧,虽然不难,但是不知道为什么就是看了很久,可能很久没有做算法题了.最后面一句话说的 ...

  10. 微信小程序开发技巧总结 (一)-- 数据传递和存储

    结合自己在平时的开发中遇到的各种问题,和浏览各种问题的解决方案总结出一些自己在日常开发中常用的技巧和知点,希望各位不吝斧正. 1.短生命周期数据存储 以小程序启动到彻底关闭为周期的的数据建议存储在ap ...