AcWing 1215. 小朋友排队 (树状数组)

添加链接描述

这个题其实需要证明一下答案就是每个数加上其前大于自己和其后小于自己的数,这就是每个数需要加的次数,用贪心法想到这个,然后证明其正确性

其实是一个逆序对的问题,但是暴力求解会超时,需要用树状数组优化。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;

class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter pw = new PrintWriter(System.out);
    static int N = 1000010, n;
    static int sum[] = new int[N], tr[] = new int[N], h[] = new int[N];

    public static void main(String[] args) throws Exception {

        n = Integer.parseInt(br.readLine());
        String s[] = br.readLine().split(" ");
        for (int i = 0; i < n; i++) h[i] = Integer.parseInt(s[i]);

        for (int i = 0; i < n; i++) {
            sum[i] = query(N - 1) - query(h[i]);
            add(h[i], 1);
        }

        Arrays.fill(tr, 0);

        for (int i = n - 1; i >= 0; i--) {
            sum[i] += query(h[i] - 1);
            add(h[i], 1);
        }

        long res = 0;
        for (int i = 0; i < n; i++) res += (long) sum[i] * (sum[i] + 1) / 2;
        pw.print(res);

        pw.flush();
        pw.close();
        br.close();
    }

    public static int lowbit(int x) {
        return x & -x;
    }

    public static void add(int x, int v) {
        for (int i = x; i < N; i += lowbit(i)) tr[i] += v;
    }

    private static int query(int x) {
        int res = 0;
        for (int i = x; i > 0; i -= lowbit(i)) res += tr[i];
        return res;
    }
}
发布了167 篇原创文章 · 获赞 3 · 访问量 3414

猜你喜欢

转载自blog.csdn.net/qq_43515011/article/details/104389361
今日推荐