Hdu 2838 step5.3.7 (樹狀數組)

Hdu 2838 step5.3.7

Cow Sorting

 

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2081    Accepted Submission(s): 642

 

 

Problem Description

Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cowhas a unique "grumpiness" level in the range 1...100,000. Sincegrumpy cows are more likely to damage Sherlock's milking equipment, Sherlockwould like to reorder the cows in line so they are lined up in increasing orderof grumpiness. During this process, the places of any two cows (necessarilyadjacent) can be interchanged. Since grumpy cows are harder to move, it takesSherlock a total of X + Y units of time to exchange two cows whose grumpinesslevels are X and Y.

 

Please help Sherlock calculate the minimaltime required to reorder the cows.

 

 

Input

Line 1: A single integer: N

Lines 2..N + 1: Each line contains a singleinteger: line i + 1 describes the grumpiness of cow i.

 

 

Output

Line 1: A single line with the minimal timerequired 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 withrespective grumpiness levels 2, 3, and 1.

Output Details

 

2 3 1 : Initial order.

2 1 3 : After interchanging cows withgrumpiness 3 and 1 (time=1+3=4).

1 2 3 : After interchanging cows withgrumpiness 1 and 2 (time=2+1=3).

 

 

 

Source

2009 Multi-University Training Contest 3 -Host by WHU

題解:

這道題用的是樹狀數組,因爲是算相鄰牛交換,然後達到不遞減的效果,每次的代價是兩隻牛的暴力值相加,。根據題意,可知我們要算的是,在當前牛cows前面有多少暴力值比它大的牛。交換當前牛的代價是到當前牛的總暴力值ssum,減去順序暴力值的總和sum,在加上逆序暴力牛的只數*當前牛的暴力值(len2-len1)*cows。即ans += ssum – sum + (len2-len1)*cows。而計算sum的值就可以用樹狀數組——將當前牛的暴力值加入到樹狀數組中add(cows,cows),不排除有相等的暴力值,所以要記錄重複暴力值的個數,用dc[cows]記錄,而計算到當前這個暴力值,比它小的牛的暴力值的總和,用getsum(cows),然後計算出有多少個比當前牛小或者相等的值,len2 += dc[x];因爲這道題的值是比較大的,所以要用__int64,而且最後在計算ans的時候所有的值都要轉換爲__int64來計算,不然會出錯。

源代碼:

#include <iostream>

#include <stdio.h>

#include <algorithm>

using namespace std;

#define MAX 100050

int cows,len1,len2;

__int64 c[100050];

int dc[100050];

 

int lowbit(int x)

{

   returnx&(-x);

}

 

void add(int x,int num)

{

   while(x> 0 && x < MAX)

   {

     c[x] += num;

     dc[x]++;

     x += lowbit(x);

   }

}

 

__int64 getsum(int x)

{

   __int64sum = 0;

   while(x> 0 && x < MAX)

   {

     sum += c[x];

     len2 += dc[x];

     x -= lowbit(x);

   }

   returnsum;

}

 

int main()

{

   intn;

   __int64ans,ssum,sum;

   while(scanf("%d",&n)!=EOF)

   {

     ans = 0;

     ssum = 0;

     memset(c,0,sizeof(c));

     memset(dc,0,sizeof(dc));

     for(int i = 0;i < n;i++)

     {

        scanf("%d",&cows);

        add(cows,cows);

        ssum += (__int64)cows;

        len1 = i+1;

        len2 = 0;

        sum = getsum(cows);

        ans += ssum - sum +(len1-len2)*(__int64)cows;

     }

     printf("%I64d\n",ans);

   }

   return0;

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章