数状数组简单应用 小鱼比可爱 数据加强版十万;

题目描述

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

输入输出格式

输入格式:

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

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

输出格式:

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

输入输出样例

输入样例#1: 复制
6
4 3 0 5 1 2
输出样例#1: 复制
0 0 0 3 1 2

说明

n<=100000

分析:

因为数据很大,需要进行数据缩小;

找到每个小鱼左边比他数值小的,有输入先后问题,所以输入一个,输出一个;

以每个数字出现的次数来建树,建树的时候,输入一个数字一路把次数加一;

void change(int k)
{
    while(k<=100001)
    {
        tree[k]++;//加一而不加上数据了
        k+=lowbit(k);
    }
}
怎样缩小数字:
两遍排序;
第一遍按数字排,然后按顺序更改数字为i
第二遍按编号排,回到原来的顺序;
 sort(a,a+n,com1);
       for(int i=0;i<n;i++)a[i].num=i;
       sort(a,a+n,com2);
总代码:
#include<bits/stdc++.h>
using namespace std;
int tree[10001],n;
struct node
{
    int rank,num;
};node a[10001];
bool com1(node x,node y);//按数字
bool com2(node x,node y);//按编码
int lowbit(int x)
{return x&(-x);}
void change(int k);//建树
int getsum(int k);//查找
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&a[i].num),a[i].rank=i;//输入数据附带编码
       sort(a,a+n,com1);for(int i=0;i<n;i++)a[i].num=i;//排数字改数字
       sort(a,a+n,com2);
    for(int i=0;i<n;i++)
    {printf("%d ",getsum(a[i].num));
        change(a[i].num+1);
    }
}
void change(int k)
{
    while(k<=10001)
    {tree[k]++;k+=lowbit(k);}
}
int getsum(int k)
{ int sum=0;
    while(k)
    { sum+=tree[k];k-=lowbit(k); }
    return sum;
}
bool com1(node x,node y)
{
    if(x.num<y.num)return 1;
    else 
      if(x.num==y.num)
    {
        if(x.rank<y.rank)return 1;
        else return 1;
    }
      else
      return 0;
}
bool com2(node x,node y)
{
    if(x.rank<y.rank)return 1;
    else return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐行tag

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值