zoukankan      html  css  js  c++  java
  • Jzoj3542 冒泡排序

    下面是一段实现冒泡排序算法的C++代码:

    for (int i=1;i<=n;i++)

     for (int j=1;j<=n-i;j++)

    if (a[j]>a[j+1]) swap(a[j],a[j+1]);

    其中待排序的a数组是一个1~n的排列,swap函数将交换数组中对应位置的值。

    对于给定的数组a以及给定的非负整数k,使用这段代码执行了正好k次swap操作之后数组a中元素的值会是什么样的呢?

    是一个模拟题也~

    我们先来考虑一个数的移动情况

    假设x前面有t[x]个数比x要大,那么显然在i<=t[x]的时候,x每次都会被前移一位,之后就不会再向前了

    又因为,前移的次数=swap的次数,所以我们可以先求出t数组,让后二分i,使得swap的次数不超过k

    设枚举出来的这个i的上界为m,那么所有t[x]>=m的数必然前移了m位,让后我们将所有t[x]<m的x拿出来排序,然后插入回原来的空格中(显然这部分的数是排序好了的,因为这些数不会再前移,所以必然有序)

    最后由于没到k次,差的部分直接用模拟补上

    #pragma GCC opitmize("O3")
    #pragma G++ opitmize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int n,v[1000010],t[1000010],b[1000010]; long long k;
    struct fenwick{
    	long long w[1000010],s;
    	inline void clear(){ memset(w,0,sizeof w); }
    	inline void add(int x,int v=1){ for(;x<=n;x+=x&-x) w[x]+=v; }
    	inline long long sum(int x){ for(s=0;x;x&=x-1) s+=w[x]; return s; }
    } r,c;
    int main(){
    	scanf("%d%lld",&n,&k);
    	for(int i=1;i<=n;++i){
    		scanf("%d",v+i);
    		t[i]=i-r.sum(v[i])-1; r.add(v[i]);
    	}
    	r.clear();
    	for(int i=1;i<=n;++i) r.add(t[i]+1),c.add(t[i]+1,t[i]);
    	int l=0,R=n;
    	for(int m;l<R;){
    		m=l+R+1>>1;
    		if(k>=c.sum(m+1)+m*(n-r.sum(m+1))) l=m;
    		else R=m-1;
    	}
    	k-=c.sum(l+1)+l*(n-r.sum(l+1));
    	for(int i=1;i<=n;v[i++]=0)
    		if(t[i]>=l)v[i-l]=v[i]; else b[++*b]=v[i];
    	sort(b+1,b+1+*b);
    	for(int i=n;i;--i) if(!v[i]) v[i]=b[(*b)--];
    	for(int j=1;j<n && k;++j)
    		if(v[j]>v[j+1]) swap(v[j],v[j+1]),--k;
    	if(k) puts("Impossible!"); else 
    		for(int j=1;j<=n;++j) printf("%d ",v[j]);
    }

  • 相关阅读:
    delphi字符串固定长度换行
    delphi存取图片
    fastreport字体加粗
    delphi 连接oracle对接代码
    Trystrtofloat
    去掉整数前面多余的0
    查询字符串第一次出现的数字
    字符串
    详细理解servlet实现的三种方式和生命周期
    Tomcat源码解析-整体流程介绍
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477178.html
Copyright © 2011-2022 走看看