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 }
越努力,越幸运