HDU-5775-Bubble Sort(线段树)

来源:互联网 发布:c语言bool类型 编辑:程序博客网 时间:2024/06/05 02:12

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5775

题意:根据题目中的冒泡排序方法,问排序过程中每个数据的最大位移差。

题解:观察代码可以知道当前数字移动之前需要先把其后面小的数移动到前面,那么得到最右位置,最左位置取排序前位置和排序后位置的最小值即可。


考虑一个位置上的数字c在冒泡排序过程的变化情况。c会被其后面比c小的数字各交换一次,之后c就会只向前移动。数组从右向左扫,树状数组维护一下得到每个值右边有多少个比其小的值,加上原位置得到最右位置,最左位置为初始位置和最终位置的最小值。

时间复杂度O(n\ lg\ n)O(n lg n)

code:


#include <bits/stdc++.h>using namespace std;#define bug cout<<"bug"<<endl#define INF 0x3f3f3f3f#define mod 1000000007const int maxn = 1e5+7;int a[maxn],b[maxn],temp[maxn<<1];void updata(int l, int r, int poi, int p){    if(l==r){temp[poi]=1;return;}    int mid=(l+r)>>1;    if(mid>=p)updata(l,mid,poi<<1,p);    if(mid<p) updata(mid+1,r,poi<<1^1,p);    temp[poi]=temp[poi<<1]+temp[poi<<1^1];}int query(int l, int r, int poi, int a, int b){    if(a<=l && r<=b)return temp[poi];    int mid=(l+r)>>1,ans=0;    if(mid>=a)ans+=query(l,mid,poi<<1,a,b);    if(mid<b)ans+=query(mid+1,r,poi<<1^1,a,b);    return ans;}int main(){   int T,n,p,cas=1;   scanf("%d",&T);   while(T--)   {       memset(temp,0,sizeof(temp));       memset(a,0,sizeof(a));       scanf("%d",&n);       for(int i=0; i<n; ++i)       {           scanf("%d",&p);           updata(1,n,1,p);           if(p==1){a[p]=i+1-p;continue;}           a[p]=query(1,n,1,1,p-1);           a[p]=p-1-a[p]+i;           a[p]=max(a[p]-i,a[p]-p+1);       }       printf("Case #%d:",cas++);        for(int i=1; i<=n; ++i)            printf(" %d",a[i]);        printf("\n");   }}/*233 1 231 2 3562 3 6 1 5 484 1 2 5 3 7 6 872 5 1 4 7 6 361 2 3 4 6 5*/


0 0
原创粉丝点击