AcWing 241. 楼兰图腾(树状数组求逆序对)

题目链接:点击这里
在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
typedef long long ll;
const int N = 200010;

int n;
int a[N], tr[N];
int left_bg[N], left_sm[N];
int right_bg[N], right_sm[N];

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

void add(int x, int c)
{
    for(int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}

int sum(int x)
{
    int res = 0;
    for(int i = x; i; i -= lowbit(i))   res += tr[i];
    return res;
}

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    
    for(int i = 1; i <= n; ++i)
    {
        int y = a[i];
        left_bg[i] = sum(n) - sum(y);    // [y+1, n]
        left_sm[i] = sum(y - 1);         // [1, y-1]
        add(y, 1);
    }
    
    memset(tr, 0, sizeof tr);
    
    for(int i = n; i >= 1; --i)
    {
        int y = a[i];
        right_bg[i] = sum(n) - sum(y);   // [y+1, n]
        right_sm[i] = sum(y - 1);        // [1, y-1]
        add(y, 1);
    }
    
    ll res1 = 0, res2 = 0;
    for(int i = 1; i <= n; ++i)
    {
        res1 += (ll)left_bg[i] * right_bg[i];
        res2 += (ll)left_sm[i] * right_sm[i];
    }
    
    printf("%lld %lld\n", res1, res2);
    return 0;
}
发布了844 篇原创文章 · 获赞 135 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/105169620