hdu-2838 Cow Sorting---逆序对的花费

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2838

题目大意:

就是求将之前的排列变成一个递增的排列,每交换两个数的代价为两个数的和,求变成递增的排列所需的最小代价为多少。

其实就是求出逆序对的花费(每对逆序对的花费是这个逆序对的和)

解题思路:

用两个树状数组维护即可,一个维护逆序对的数目,一个维护逆序对的值的和

注意:全部用long long

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<map>
 6 #include<set>
 7 #include<cmath>
 8 #include<algorithm>
 9 #include<vector>
10 #include<sstream>
11 #define lowbit(i) (i&(-i))
12 using namespace std;
13 const int maxn = 1e6 + 10;
14 typedef long long ll;
15 ll tree_sum[maxn], tree_num[maxn], n;
16 void add(ll x, ll d, ll tree[])
17 {
18     while(x <= n)tree[x] += d, x += lowbit(x);
19 }
20 ll sum(ll x, ll tree[])
21 {
22     ll ans = 0;
23     while(x)
24         ans += tree[x], x -= lowbit(x);
25     return ans;
26 }
27 int main()
28 {
29     while(scanf("%lld", &n) != EOF)
30     {
31         ll x, ans = 0;
32         memset(tree_num, 0, sizeof(tree_num));
33         memset(tree_sum, 0, sizeof(tree_sum));
34         for(int i = 1; i <= n; i++)
35         {
36             scanf("%lld", &x);
37             add(x, 1, tree_num);
38             add(x, x, tree_sum);
39             ans += (sum(n, tree_num) - sum(x, tree_num)) * x + sum(n, tree_sum) - sum(x, tree_sum);
40         }
41         cout<<ans<<endl;
42     }
43     return 0;
44 }

 

posted @ 2018-04-26 22:22  _努力努力再努力x  阅读(122)  评论(0编辑  收藏  举报