• 小和问题


    在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组得小和.

    比如[1,3,4,2]1左边比1小的数没有,3左边比3小的数有1,4左边比4小的数有1,3,2左边比2小的数有1.那么这个数组的小和是

    1+1+3+1=6

     暴力方法是每次遍历的时候,都要再把前面的比较一下,这样时间复杂度是O(n^2)这样明显不行,仔细思考下过程,就是归并排序的过程之中,

    在你进行归并的时候,你需要左边比右边小的时候记录下来,进行累加,可以算出右边有多少个数比它大,代码如下:

    public static int getSmallSum(int[] a, int l, int r) {
            if (l >= r || a.length == 1)
                return 0;
            int mid = l + ((r - l) >> 1);
            //左边求小和加右边求小和加整体求整体小和
            return getSmallSum(a, l, mid) +
                    getSmallSum(a, mid + 1, r) +
                    process(a, l, mid, r);
        }
    
        private static int process(int[] a, int l, int mid, int r) {
            int[] aux = new int[r - l + 1];
            int lo = l;
            int hi = mid + 1;
            int index = 0;
            int sum = 0;
            while (lo <= mid && hi <= r) {
                if (a[lo] < a[hi]) {
                    //左边只有小才能算是小和,相等不算
                    sum = sum + (r - hi + 1) * a[lo];
                    aux[index++] = a[lo++];
                } else {
                    aux[index++] = a[hi++];
                }
            }
            while (lo <= mid) {
                aux[index++] = a[lo++];
            }
            while (hi <= r) {
                aux[index++] = a[hi++];
            }
            for (int aux1 : aux) {
                a[l++] = aux1;
            }
            return sum;
        }
  • 相关阅读:
    洛谷P3258 [JLOI2014]松鼠的新家
    洛谷P3128 [USACO15DEC]最大流Max Flow
    Bzoj1651: [Usaco2006 Feb]Stall Reservations 专用牛棚
    2017-9-26 NOIP模拟赛
    洛谷P1441 砝码称重
    洛谷P1275 魔板
    洛谷P2037 电话号码
    2014-11-3 NOIP模拟赛2
    洛谷P3102 [USACO14FEB]秘密代码Secret Code
    洛谷P3070 [USACO13JAN]岛游记Island Travels
  • 原文地址:https://www.cnblogs.com/junalncer/p/13079533.html
Copyright © 2020-2023  润新知