加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

hdu 2838 Cow Sorting 树状数组求所有比x小的数的个数

发布时间:2020-12-15 07:41:48 所属栏目:Java 来源:网络整理
导读:Cow Sorting Time Limit: 2000/1000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4766????Accepted Submission(s): 1727 Problem Description Sherlock‘s N (1 ≤ N ≤ 100,000) cows are lined up to be milked

Cow Sorting

Time Limit: 2000/1000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4766????Accepted Submission(s): 1727


Problem Description
Sherlock‘s N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cows are more likely to damage Sherlock‘s milking equipment,Sherlock would like to reorder the cows in line so they are lined up in increasing order of grumpiness. During this process,the places of any two cows (necessarily adjacent) can be interchanged. Since grumpy cows are harder to move,it takes Sherlock a total of X + Y units of time to exchange two cows whose grumpiness levels are X and Y.

Please help Sherlock calculate the minimal time required to reorder the cows.
?

?

Input
Line 1: A single integer: N
Lines 2..N + 1: Each line contains a single integer: line i + 1 describes the grumpiness of cow i.
?

?

Output
Line 1: A single line with the minimal time required to reorder the cows in increasing order of grumpiness.
?

?

Sample Input
3 2 3 1
?

?

Sample Output
7
Hint
Input Details Three cows are standing in line with respective grumpiness levels 2,3,and 1. Output Details 2 3 1 : Initial order. 2 1 3 : After interchanging cows with grumpiness 3 and 1 (time=1+3=4). 1 2 3 : After interchanging cows with grumpiness 1 and 2 (time=2+1=3).
?
?
题意:?n个数的排列,每次可以互换相邻的元素,最终变成一个递增的序列,每次互换的代价为互换的两个数的和,求最小代价。
?
题解:从无序到递增过程,就是冒泡排序的过程。对于每一个元素a[i],需要交换的次数就是在a[1]~a[i-1]中,所有比a[i]大的元素的个数cnt,a[i]到最终状态花费的代价就是cnt*a[i]+所有被交换的元素的和sum
树状数组处理出? 比a[i]小的数的个数b[i] 和 所有比a[i]小的数的和c[i]就可以直接处理
?
#include<iostream>
#include<string.h>
#define ll long long
using namespace std;
ll a[100005],b[100005],c[100005];
//a[i]保存原始数据,b[i]保存比a[i]小的数的个数,c[i]保存所有比a[i]小的数的和
ll lowbit(ll x)
{
    return x&(-x);
}

ll getnum(ll x)//求比x小的数的个数
{
    ll cnt=0;
    while(x>0)
    {
        cnt=cnt+b[x];
        x=x-lowbit(x);
    }
    return cnt;
}

ll getsum(ll x)//求比x小的数的和
{
    ll ans=0;
    while(x>0)
    {
        ans=ans+c[x];
        x=x-lowbit(x);
    }
    return ans;
}

void add(ll x,ll y)//更新,对第x个位置的数进行更新,y是更新值
{
    while(x<=100000)
    {
        b[x]=b[x]+1;
        c[x]=c[x]+y;
        x=x+lowbit(x);
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        ll ans=0,sum=0;
        memset(a,sizeof(a));
        memset(b,sizeof(b));
        memset(c,sizeof(c));
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            add(a[i],a[i]);//将第x个位置的值,修改为x
            sum=sum+a[i];//sum求所有数的和
            ans=ans+a[i]*(i-getnum(a[i]));//i-getnum(a[i])是比a[i]大的数的个数
            ans=ans+sum-getsum(a[i]);//sum-getsum(a[i])是所有比a[i]大的数的和
        }
        printf("%lldn",ans);
    }
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读