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

题目描述

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

输入输出格式

输入格式:

第一行输入一个整数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;
}




猜你喜欢

转载自blog.csdn.net/k42946/article/details/80765038