zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    Vasya and Endless Credits CodeForces
    Dreamoon and Strings CodeForces
    Online Meeting CodeForces
    数塔取数 基础dp
    1001 数组中和等于K的数对 1090 3个数和为0
    1091 线段的重叠
    51nod 最小周长
    走格子 51nod
    1289 大鱼吃小鱼
    POJ 1979 Red and Black
  • 原文地址:https://www.cnblogs.com/10jschen/p/2669304.html
Copyright © 2011-2022 走看看