小鱼比可爱(加强版)--归并排序

Description

.人比人,气死人;鱼比鱼,难死鱼。小鱼最近参加了一个“比可爱”比赛,比的是每只鱼的可爱程度。参赛的鱼被从左到右排成一排,头都朝向左边,然后每只鱼会得到一个整数数值,表示这只鱼的可爱程度,很显然整数越大,表示这只鱼越可爱,而且任意两只鱼的可爱程度可能一样。由于所有的鱼头都朝向左边,所以每只鱼只能看见在它左边的鱼的可爱程度,它们心里都在计算,在自己的眼力范围内有多少只鱼不如自己可爱呢。请你帮这些可爱但是鱼脑不够用的小鱼们计算一下。

Input

第一行输入一个整数n,表示鱼的数目。

第二行内输入n个整数,用空格间隔,依次表示从左到右每只小鱼的可爱程度。

Output

行内输出n个整数,用空格间隔,依次表示每只小鱼眼中有多少只鱼不如自己可爱。

Sample Input 1

6
4 3 0 5 1 2

Sample Output 1

0 0 0 3 1 2

Hint

1<=n<=10^6

思路

有两种解法
第一种是普通归并排序,增加一个 灵性的tt变量 储存大于左边的值。

#include<bits/stdc++.h>
using namespace std;
const int m = 1000005;
struct aa
{
	int v, p;//v:value值 p:position位置
}a[m];
int ans[m];
int read() {//快读
	char c = getchar();
	int fu = 1;
	while (c < '0' || c>'9') {
		if (c == '-')
			fu = -1;
		else
			fu = 1;
		c = getchar();
	}
	int t = 0;
	while (c >= '0' && c <= '9') {
		t = (t << 3) + (t << 1) + (c ^ 48);
		c = getchar();
	}
	return t * fu;
}
void Merge(aa a[], int lb, int le, int re)
{
	int tlb = lb;
	int rb = le + 1;
	int mb = lb;
	//lb:left begin le:left end
	//rb:left begin re:right end 
	//mb:merge数组指针
	aa t[m];
	int tt = 0;//现在 左边有多少个数 比 右边当前数字小
	while (mb <= re)//
	{
		
		if (rb > re)
		{
			for (int i = lb; i <= le; i++)
			{
				t[mb++] = a[i];
			}
			break;
		}
		else if(lb>le)
		{
			for (int i = rb; i <= re; i++)
			{
				ans[a[i].p] += tt;//由于左边可能因为 lb超出 而导致 右边数字未能全部遍历,要增加此语句进行补全
				t[mb++] = a[i];
			}
			break;
		}
		if (a[rb].v > a[lb].v) {
			tt++;//当前的左边值比右边值小
			t[mb++] = a[lb++];
		}
		else
		{
			ans[a[rb].p] += tt;//加上 左边比他小的数
			t[mb++] = a[rb++];
		}
		
	}
	for (int i = tlb; i <= re; i++)a[i] = t[i];
}
void MergeSort(aa a[],int left,int right)
{
	if (left >= right)return;
	int mid = left + ((right - left)>>1);
	MergeSort(a,left,mid);
	MergeSort(a,mid+1, right);
	Merge(a,left, mid, right);
}
int main()
{
	int n = read();
	for (int i = 0; i < n; i++)
	{
		a[i].v = read();
		a[i].p = i;
	}
	MergeSort(a, 0, n - 1);
	for (int i = 0; i < n; i++)
	{
		printf("%d ", ans[i]);
	}
	return 0;
}

第二种解法比较巧妙,归并排序时 从大到小实现 这样ans每次加 只需要加 左边的 未遍历过的(一定比他小) 就可以了

#include<bits/stdc++.h>
using namespace std;
const int m = 1000005;
struct aa
{
	int v, p;
}a[m];
int ans[m];
int read() {
	char c = getchar();
	int fu = 1;
	while (c < '0' || c>'9') {
		if (c == '-')
			fu = -1;
		else
			fu = 1;
		c = getchar();
	}
	int t = 0;
	while (c >= '0' && c <= '9') {
		t = (t << 3) + (t << 1) + (c ^ 48);
		c = getchar();
	}
	return t * fu;
}
void Merge(aa a[], int lb, int le, int re)
{
	int tlb = lb;
	int rb = le + 1;
	int mb = lb;
	aa t[m];
	while (mb <= re)//
	{
		if (rb > re)
		{
			for (int i = lb; i <= le; i++)
			{
				t[mb++] = a[i];
			}
			break;
		}
		else if(lb>le)
		{
			for (int i = rb; i <= re; i++)
			{
				t[mb++] = a[i];
			}
			break;
		}
		if (a[lb].v < a[rb].v) {
			ans[a[rb].p] += le - lb + 1;
			t[mb++] = a[rb++];
		}
		else
		{
			t[mb++] = a[lb++];
		}
		
	}
	for (int i = tlb; i <= re; i++)a[i] = t[i];
}
void MergeSort(aa a[],int left,int right)
{
	if (left >= right)return;
	int mid = left + ((right - left)>>1);
	MergeSort(a,left,mid);
	MergeSort(a,mid+1, right);
	Merge(a,left, mid, right);
}
int main()
{
	int n = read();
	for (int i = 0; i < n; i++)
	{
		a[i].v = read();
		a[i].p = i;
	}
	MergeSort(a, 0, n - 1);
	for (int i = 0; i < n; i++)
	{
		printf("%d ", ans[i]);
	}
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值