HDU 1394(线段树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394

区间求和问题,但是用暴力方法也能通过,线段树50MS可以解决,暴力要250多MS,这就是算法的魅力所在~~~

线段树代码:

 1 #include <stdio.h>
 2 #define L(x) ((x) << 1)
 3 #define R(x) ((x) << 1 | 1)
 4 #define N 5001
 5 
 6 typedef struct
 7 {
 8     int lson, rson;
 9     int val;
10 }   seg_tree;
11 seg_tree s[N << 2];
12 int num[N];
13 
14 void build(int left, int right, int idx)
15 {
16     s[idx].lson = left;
17     s[idx].rson = right;
18     s[idx].val = 0;
19     if(left == right)
20     {
21         return;
22     }
23     int mid = (left + right) / 2;
24     build(left, mid, L(idx));
25     build(mid + 1, right, R(idx));
26 }
27 
28 void update(int id, int idx)
29 {
30     s[idx].val++;
31     if(s[idx].lson == s[idx].rson)
32     {
33         return;
34     }
35     int mid = (s[idx].lson + s[idx].rson) / 2;
36     if(id <= mid)
37     {
38         update(id, L(idx));
39     }
40     else
41     {
42         update(id, R(idx));
43     }
44 }
45 
46 int query(int left, int right, int idx)
47 {
48     if(left == s[idx].lson && s[idx].rson == right)
49     {
50         return s[idx].val;
51     }
52     int mid = (s[idx].lson + s[idx].rson) / 2;
53     if(right <= mid)
54     {
55         return query(left, right, L(idx));
56     }
57     else if(left > mid)
58     {
59         return query(left, right, R(idx));
60     }
61     else
62     {
63         return query(left, mid, L(idx)) + query(mid + 1, right, R(idx));
64     }
65 }
66 
67 int main()
68 {
69     int n;
70     while(scanf("%d", &n) != EOF)
71     {
72         int i;
73         int sum = 0;
74         build(1, n, 1);
75         for(i = 1; i <= n; i++)
76         {
77             scanf("%d", &num[i]);
78             sum += query(num[i] + 1, n, 1);
79             update(num[i] + 1, 1);
80         }
81         int res = sum;
82         for(i = 1; i <= n; i++)
83         {
84             sum = sum - num[i] + (n - num[i] - 1);
85             if(res > sum)
86                 res = sum;
87         }
88         printf("%d\n", res);
89     }
90     return 0;
91 }

暴力求解代码:

#include <stdio.h>
#include <string.h>
#define N 5001

int a[N];
int b[N];

int main()
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        memset(b, 0, sizeof(b));
        int i, j, t = 0;
        for(i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
        }
        for(i = 0; i < n; i++)
        {
            for(j = i + 1; j < n; j++)
            {
                if(a[i] > a[j])
                {
                    b[i]++;
                }
            }
            t += b[i];
        }
        int min = t;
        for(i = 0; i < n; i++)
        {
            t = t - a[i] + (n - a[i] - 1);
            if(min > t)
            {
                min = t;
            }
        }
        printf("%d\n", min);
    }
}
posted @ 2012-09-03 19:13  山路水桥  阅读(651)  评论(0编辑  收藏  举报