zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    生命游戏评价
    Unsupervised Person Re-identification by Soft Multilabel Learning
    Transferable Joint Attribute-Identity Deep Learning for Unsupervised Person Re-Identification理解
    神经网络可视化《Grad-CAM:Visual Explanations from Deep Networks via Gradient-based Localization》
    HHL论文及代码理解(Generalizing A Person Retrieval Model Hetero- and Homogeneously ECCV 2018)
    StarGAN论文及代码理解
    windows版anaconda+CUDA9.0+cudnn7+pytorch+tensorflow安装
    迁移学习
    Training a classifier
    Neural Networks
  • 原文地址:https://www.cnblogs.com/Grice/p/12360544.html
Copyright © 2011-2022 走看看