您的位置:首页 > 大数据 > 人工智能

树状数组 ( 求逆序数 )——Bubble Sort ( HDU 5775 ) ( 2016 Multi-University Training Contest 4 1012 )

2016-07-28 20:05 525 查看
题目链接:

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

分析:

给出N个数,将这几个数进行题中所述的“冒泡排序”,求每个数在排序过程中(包括始末状态)所达到的坐标的最大差值。

题解:

①我们可以先求出每个数在排序过程中所能达到最靠后的位置 loc ,然后 loc - min ( 起始点,终止点 ) 就是要求的最大差值。

②而每个点能移动到的最靠后的位置 loc 可以这样求:每个数前面比它大的数的个数 + 这个数的最终位置(可以通过找规律发现)。

③每个数前面比它大的数 即 逆序数 可以通过树状数组求得:

int n;//一共多少个数
int c
;

int Lowbit(int x)
{
return x & (-x);
}
void Update(int t,int val)
{
for(int i=t; i<=n; i+=Lowbit(i))
c[i] += val;
}
int getSum(int x)
{
int ans=0;
for(int i=x; i>0; i-=Lowbit(i))
ans += c[i];
return ans;
}
//题解如下:
for(int i=1;i<=n;i++)
{
Update(a[i], 1);
int x = i - getSum(a[i]);//逆序数个数(a[i]之前大于a[i]数目的个数)
int loc = x + a[i];//最远位置
int ans = loc - min(a[i], i);//a[i]的最大差值
b[a[i]] = ans;  //存入答案数组
}


AC代码:

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <string>
#include <map>
#include <set>
#include <queue>
using namespace std;
typedef pair<int,int> Pii;
typedef long long LL;
typedef unsigned long long ULL;
typedef double DBL;
typedef long double LDBL;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))

#define N 112345
int n;
int c
;
int a
;
int Lowbit(int x)
{
return x & (-x);
}
void Update(int t,int val)
{
for(int i=t; i<=n; i+=Lowbit(i))
c[i] += val;
}
int getSum(int x)
{
int ans=0;
for(int i=x; i>0; i-=Lowbit(i))
ans += c[i];
return ans;
}

int b
;
int main()
{
int T;
int tt = 1;
scanf("%d", &T);
while(T--)
{
CLR(c);
CLR(b);
scanf("%d", &n);
for(int i=1;i<=n;i++)
{
scanf("%d", &a[i]);
}
for(int i=1;i<=n;i++)
{
Update(a[i], 1);
int x = i - getSum(a[i]);
int loc = x+a[i];
int ans = loc - min(a[i], i);
b[a[i]] = ans;
}
printf("Case #%d: ", tt++);
for(int i=1;i<n;i++)
printf("%d ", b[i]);
printf("%d\n", b
);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息