zoukankan      html  css  js  c++  java
  • [USACO18OPEN] Out of Sorts P JZOJ 100136 冒泡的胖头鱼(冒泡排序性质)

    题解:

    显然对整个序列考虑不行,不如对每一个元素单独考虑。

    一个元素x在x和x+1都成为分割点前显然会被一直计算答案,设(T(x))表示x分割点出现的时间。

    那么(Ans=sum_{i=1}^n max(T(i-1),T(i)))

    众所周知,冒泡排序都是去考虑每一个元素的往左移动,而不是往右移动。

    对冒泡排序的一个元素(a[i]),若它前面有(k)个比他大的数,那么前(k)轮它都会往前移动一格。

    对于这题,只要(1..x)的元素全部退到(x)以前,就有(x)这个分割点了。

    所以设(b[i])(i)大的元素所在的位置,(T(x)=max(b[i]-x)(iin[1,x]))

    这题有相同的元素,由于冒泡排序是稳定排序,所以相同的元素就考虑它们原来的位置就好了。

    Code:

    #include<bits/stdc++.h>
    #define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
    #define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
    #define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
    #define ll long long
    #define pp printf
    #define hh pp("
    ")
    using namespace std;
    
    const int N = 1e5 + 5;
    
    int n, a[N], b[N], mx;
    ll ans;
    
    int cmpb(int x, int y) {
    	if(a[x] == a[y]) return x < y;
    	return a[x] < a[y];
    }
    
    int main() {
    	scanf("%d", &n);
    	fo(i, 1, n) scanf("%d", &a[i]), b[i] = i;
    	sort(b + 1, b + n + 1, cmpb);
    	int t1 = 0, t2;
    	fo(i, 1, n) {
    		mx = max(mx, b[i]);
    		t2 = max(mx - i, 1);
    		ans += max(t1, t2); t1 = t2;
    	}
    	pp("%lld
    ", ans);
    }
    
  • 相关阅读:
    微软面试智力题
    苹果下好用的中文输入法
    Programming on Mac OS X Learn ObjectC Serials (1)
    Mac OS X Glut build instructions
    window.opener 的用法
    jboss5.1.0.GA :org.apache.tomcat.jni.Error
    分账模式助力电子商务
    SON JAVA 使用方法
    网站功能用语
    如何在spring框架中解决多数据源的问题
  • 原文地址:https://www.cnblogs.com/coldchair/p/12361555.html
Copyright © 2011-2022 走看看