HDU - 5775 - Bubble Sort

P is a permutation of the integers from 1 to N(index starting from 1).
Here is the code of Bubble Sort in C++.

for(int i=1;i<=N;++i)
for(int j=N,t;j>i;—j)
if(P[j-1] > P[j])
t=P[j],P[j]=P[j-1],P[j-1]=t;

After the sort, the array is in increasing order. ?? wants to know the absolute values of difference of rightmost place and leftmost place for every number it reached.
Input
The first line of the input gives the number of test cases T; T test cases follow.
Each consists of one line with one integer N, followed by another line with a permutation of the integers from 1 to N, inclusive.

limits
T <= 20
1 <= N <= 100000
N is larger than 10000 in only one case.
Output
For each test case output “Case #x: y1 y2 … yN” (without quotes), where x is the test case number (starting from 1), and yi is the difference of rightmost place and leftmost place of number i.
Sample Input
2
3
3 1 2
3
1 2 3
Sample Output
Case #1: 1 1 2
Case #2: 0 0 0

[分析]
先要看题目所给的冒泡,他的思路是小的往左边移动。
有的数字所在的位置比本该在的位置大,所以他要往左边主动移动。
有的数字所在的位置比本该在的位置小,因为冒泡是移动小的,所以这些数字都不是主动移动的,他们是因为其他的数字移动了,所以被动往右移动。
知道了这些你就可以分析出,左位置只能是min(a[i], i);,(因为被动移动只会向右边移动)
右位置必然是当前位置加上你右边有多少比你小的数i + (a[i] - 1 - sum(a[i]));
右边有多少比你小的数通过树状数组计算,非常方便

[代码]

#include <cstdio>  
#include <cstring>  
#include<algorithm>
using namespace std;
#define maxn 100005
int c[maxn];
int a[maxn];

struct ANS
{
    int l, r;
}ans[maxn];

int Lowbit(int x)  // 2^k
{
    return x&(-x);
}
void update(int i, int x)//i点增量为x
{
    while (i <= maxn)
    {
        c[i] += x;
        i += Lowbit(i);
    }
}
int sum(int x)//区间求和 [1,x]
{
    int sum = 0;
    while (x>0)
    {
        sum += c[x];
        x -= Lowbit(x);
    }
    return sum;
}

int Getsum(int x1, int x2) //求任意区间和
{
    return sum(x2) - sum(x1 - 1);
}
int main()
{
    int t,kase=0;
    scanf("%d", &t);
    while (t--)
    {
        memset(c, 0, sizeof(c));
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            //i - sum(a[i]);

            ans[a[i]].l = min(a[i], i);
            ans[a[i]].r = i + (a[i] - 1 - sum(a[i]));
            update(a[i], 1);
        }
        printf("Case #%d:", ++kase);
        for (int i = 1; i <= n; i++)
        {
            printf(" %d", abs(ans[i].l - ans[i].r));
        }
        printf("\n");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值