HDU 5775 Bubble Sort (线段树乱搞)

本文解析了HDU 5775 BubbleSort问题,介绍了使用冒泡排序算法处理整数排列的过程,并针对每个数字计算其在排序过程中左右位置变化的最大差值。通过具体示例说明了解题思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5775点击打开链接

Bubble Sort

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2096    Accepted Submission(s): 1017


Problem Description
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
Hint
In first case, (3, 1, 2) -> (3, 1, 2) -> (1, 3, 2) -> (1, 2, 3) the leftmost place and rightmost place of 1 is 1 and 2, 2 is 2 and 3, 3 is 1 and 3 In second case, the array has already in increasing order. So the answer of every number is 0.


求上面那串代码下排序每个数的左右距离差

这道题没理解透就A了。。

说一下我的操作吧。

分别对序列进行下标排序下的值逆序操作和值排序下的下标逆序操作 

然后求两个的最大值

试了两组样例发现结果一样。。

交了发然后就A了。。

尝试强行解释一下吧 也是目前我的理解

因为是求差 因此每个数在那段代码的冒泡排序下会有两种情况

一种是与后面比他小的值交换 

另一种是与比他前面大的值交换

所以最后就是要么左移要么右移  次数取最大

如果有大佬能解释下小弟感激不尽。。

#include <bits/stdc++.h>
using namespace std;
#define maxn 100010
struct xjy
{
    int left;
    int right;
    int num;
}tree[maxn<<2];
struct xxjy
{
    int num;
    int index;
};
struct xjyy
{
    int ans1;
    int ans2;
    int index;
    bool operator < (const xjyy &r)const
    {
        return index<r.index;
    }
};
int cmp1(xxjy a,xxjy b)
{
    return a.num<b.num;
}
int cmp2(xxjy a,xxjy b)
{
    return a.index<b.index;
}
xxjy a[maxn];
xjyy anss[maxn];
int ans;
int n;
void build(int root,int left,int right)
{
    tree[root].left=left;
    tree[root].right=right;
    tree[root].num=0;
    if(left==right)
        return;
    int mid=(left+right)>>1;
    build(root<<1,left,mid);
    build(root<<1|1,mid+1,right);
}
void update(int root,int left,int right)
{
    if(tree[root].left==left&&tree[root].right==right)
    {
        tree[root].num++;
        return;
    }
    int mid=(tree[root].left+tree[root].right)>>1;
    if(right<=mid)
        update(root<<1,left,right);
    else if(left>mid)
        update(root<<1|1,left,right);
    else
    {
        update(root<<1,left,mid);
        update(root<<1|1,mid+1,right);
    }
    tree[root].num=tree[root<<1].num+tree[root<<1|1].num;
}
void query(int root,int left,int right)
{
    if(tree[root].left==left&&tree[root].right==right)
    {
        ans+=tree[root].num;
        return;
    }
    int mid=(tree[root].left+tree[root].right)>>1;
    if(right<=mid)
        query(root<<1,left,right);
    else if(left>mid)
        query(root<<1|1,left,right);
    else
    {
        query(root<<1,left,mid);
        query(root<<1|1,mid+1,right);
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int cnt=1;cnt<=t;cnt++)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int mid;
            scanf("%d",&mid);
            a[i].num=mid;
            a[i].index=i;
            anss[i].index=mid;
        }
        build(1,1,n);
        sort(a+1,a+1+n,cmp2);
        for(int i=1;i<=n;i++)
        {
            ans=0;
            query(1,a[i].num,n);
            //cout << ans << endl;
            anss[i].ans2=ans;
            update(1,a[i].num,a[i].num);
        }
        sort(a+1,a+1+n,cmp1);
        build(1,1,n);
        for(int i=1;i<=n;i++)
        {
            ans=0;
            query(1,a[i].index,n);
            //cout << ans <<endl;
            anss[a[i].index].ans1=ans;
            update(1,a[i].index,a[i].index);
        }
        sort(anss+1,anss+1+n);
        printf("Case #%d:",cnt);
        for(int i=1;i<=n;i++)
        {
            printf("\n%d %d\n",anss[i].ans1,anss[i].ans2);
            printf(" %d",max(anss[i].ans1,anss[i].ans2));
        }
        printf("\n");
    }
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值