hdu-3015 Disharmony Trees---离散化+两个树状数组

题目链接:

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

题目大意:

有一些树,这些树的高度和位置给出。现在高度和位置都按从小到大排序,对应一个新的rank,任意两棵树的值为min(高度的rank) * abs(位置差的绝对值)。问所有任意两棵树的值的和是多少。

解题思路:

按照题意离散化,然后对H从大到小排序,这样可以保证前面的树高度都比当前的高(或者相等)。在计算的时候就可以使用当前的H。

POJ-1990类似

 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 lowbot(i) (i&(-i))
12 using namespace std;
13 typedef long long ll;
14 const int maxn = 1e5 + 10;
15 struct node
16 {
17     ll x, h, id;
18 }a[maxn], b[maxn];
19 bool cmp1(node a, node b)
20 {
21     return a.x < b.x;
22 }
23 bool cmp2(node a, node b)
24 {
25     return a.h < b.h;
26 }
27 bool cmp3(node a, node b)
28 {
29     return a.h > b.h;
30 }
31 int n;
32 void add(int x, int d, int tree[])
33 {
34     while(x <= n)
35         tree[x] += d, x += lowbot(x);
36 }
37 ll sum(int x, int tree[])
38 {
39     ll ans = 0;
40     while(x)
41         ans += tree[x], x -=lowbot(x);
42     return ans;
43 }
44 int tree[maxn], tree_num[maxn];
45 int main()
46 {
47     while(scanf("%d", &n) != EOF)
48     {
49         memset(a, 0, sizeof(a));
50         memset(b, 0, sizeof(b));
51         memset(tree, 0, sizeof(tree));
52         memset(tree_num, 0, sizeof(tree_num));
53         for(int i = 1; i <= n; i++)
54             scanf("%lld%lld", &a[i].x, &a[i].h), a[i].id = i;
55         sort(a + 1, a + 1 + n, cmp1);
56         for(int i = 1; i <= n; i++)
57         {
58             if(a[i].x == a[i - 1].x)b[a[i].id].x = b[a[i - 1].id].x;
59             else b[a[i].id].x = i;
60         }
61         sort(a + 1, a + 1 + n, cmp2);
62         for(int i = 1; i <= n; i++)
63         {
64             if(a[i].h == a[i - 1].h)b[a[i].id].h = b[a[i - 1].id].h;
65             else b[a[i].id].h = i;
66         }
67         //for(int i = 1; i <= n; i++)
68         //    cout<<b[i].x<<" "<<b[i].h<<endl;
69         sort(b + 1, b + 1 + n, cmp3);
70         ll ans = 0, cnt, num;
71         for(int i = 1; i <= n; i++)
72         {
73             cnt = sum(b[i].x, tree);
74             num = sum(b[i].x, tree_num);
75             ans += (num * b[i].x - cnt) * b[i].h;
76             cnt = sum(n, tree) - cnt;
77             num = i - num - 1;
78             ans += (cnt - num * b[i].x) * b[i].h;
79             add(b[i].x, b[i].x, tree);
80             add(b[i].x, 1, tree_num);
81         }
82         cout<<ans<<endl;
83     }
84     return 0;
85 }

 

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