Cow Sorting(hdu 2838)

Cow Sorting

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4259    Accepted Submission(s): 1530

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).

Source

2009 Multi-University Training Contest 3 - Host by WHU

最简单的方法就是暴力,复杂度O(n^2),绝对超时,通过分析,我们可以发现这题就是求前缀问题,我们想到用树状数组,边计算边更新,正好符合题意。只不过在这里维护的是两个数组,一个是比a[i]大的前缀数量和,一个是前缀和。

这题的思路很简单,由于只能交换相邻元素,只能从前往后依次消除逆序,主要考察的是树状数组的使用!

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
long long c[3][maxn];
int lowbit(int x)
{
    return x&(-x);
}
long long sum(int i,int x)
{
    long long ans=0;
    while(x>0)
    {
        ans+=c[i][x];
        x-=lowbit(x);
    }
    return ans;
}
void add(int i,int x,long long v)
{
    while(x<maxn)
    {
        c[i][x]+=v;
        x+=lowbit(x);
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)==1&&n)
    {
        memset(c,0,sizeof(c));
        long long ans=0;
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            long long ans1=sum(1,maxn)-sum(1,x);
            long long ans2=sum(2,maxn)-sum(2,x);
            ans+=ans1*x+ans2;
            add(1,x,1);
            add(2,x,x);
        }
        printf("%lld\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41061455/article/details/81428378