您的位置:首页 > 其它

小明的排队

2016-04-13 22:24 148 查看

小明的排队

时间限制(普通/Java):2000MS/6000MS 运行内存限制:65536KByte


比赛描述

TC是个土豪,经常给整个集训队发苹果,并且喜欢将大家排成一队根据每个人的苹果数量做出一些奇怪的事情,比如让每个人算出自己右边苹果数量比自己少的人的个数。拿别人的手短,大家对于TC的奇怪嗜好也只能牵就了。

输入

输入第一行为一个T(T <= 6)表示数据组数,每组数据包含整数n(n个人, 1<=n<=100000),以及n个整数(正整数,代表每个人相应的苹果数量)

输出

对于每组数据输出n个整数,第i个整数表示第i个人右边苹果比他的少的人的个数。

样例输入

1

4 5 2 6 1

样例输出

2 1 1 0

提示
输入请用scanf,输出请用printf

输出数据的最后一个数字后面也有空格

算法分析:求解逆序数

#include <cstdio>
#include <cstring>
int const MAX = 1e5 + 5;
int const INF = 0x7FFFFFFF;
int n, a[MAX], res[MAX];

struct DATA
{
int val, idx;
}d[MAX], a1[MAX], a2[MAX];

void merge_sort(int l, int mid, int r, DATA *d)
{
int len1 = mid - l;
int len2 = r - mid;
for(int i = 0; i < len1; i++)
a1[i] = d[i + l];
a1[len1].val = INF;
for(int i = 0; i < len2; i++)
a2[i] = d[i + mid];
a2[len2].val = INF;
int i = 0, j = 0, k = l, tmp = 0;
while(i < len1 || j < len2)
{
if(a1[i].val <= a2[j].val)
{
res[a1[i].idx] += tmp;
d[k ++] = a1[i ++];
}
else
{
if(a1[i].val != INF)
tmp ++;
d[k ++] = a2[j ++];
}
}
}

void Merge(int l, int r, DATA *d)
{
if(l == r - 1)
return;
int mid = (l + r) >> 1;
Merge(l, mid, d);
Merge(mid, r, d);
merge_sort(l, mid, r, d);
}

int main()
{
int T;
scanf("%d", &T);
while(T --)
{
memset(res, 0, sizeof(res));
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", &a[i]);
for(int i = 0; i < n; i++)
{
d[i].val = a[i];
d[i].idx = i;
}
Merge(0, n, d);
for(int i = 0; i < n; i++)
printf("%d ", res[i]);
printf("\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: