AGC014-F Strange Sorting
Posted grice
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AGC014-F Strange Sorting相关的知识,希望对你有一定的参考价值。
题意
(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
", T[ 1 ] ), 0;
}
以上是关于AGC014-F Strange Sorting的主要内容,如果未能解决你的问题,请参考以下文章