码迷,mamicode.com
首页 > 其他好文 > 详细

AGC014-F Strange Sorting

时间:2020-02-25 11:10:04      阅读:62      评论:0      收藏:0      [点我收藏+]

标签:read   inline   pen   its   元素   题意   names   math   code   

题意

\(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

标签:read   inline   pen   its   元素   题意   names   math   code   

原文地址:https://www.cnblogs.com/Grice/p/12360544.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!