1. 程式人生 > 其它 >樹狀陣列的幾個基本應用(更新ing)

樹狀陣列的幾個基本應用(更新ing)

一、求逆序對

最好能加入離散化,離散化的方式值得學習,開一個結構體,儲存輸入序,之後再按值大小排序,最後按輸入序賦值1-n。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,x,n) for(int i=x;i<=n;i++)
using namespace std;
const int N = 1000001;
int n,x,tr[N],b[N];
struct node{
    int v,p;
    bool operator<(const node &nxt) const{
        if(v==nxt.v) return p<nxt.p;
        return v<nxt.v;
    }
}a[N];
int lowbit(int x) {
    return x&-x;
}
void add(int p,int x)
{
    for(int i=p;i<=n;i+=lowbit(i)) tr[i]+=x;
}
int sum(int p)
{
    int res=0;
    for(int i=p;i;i-=lowbit(i)) res+=tr[i];
    return res; 
}
int main()
{
    ll ans=0;
    cin >> n;
    rep(i,1,n)
    {
        cin >> a[i].v;
        a[i].p=i;//p是輸入序,為啥有輸入序呢,因為直接儲存值太大了,有1e9,存不下,需要離散化,這就是離散化的關鍵一步
    }
    sort(a+1,a+n+1);
    rep(i,1,n) b[a[i].p]=i;//這一步就用上了
    rep(i,1,n)
    {
        ans+=sum(n)-sum(b[i]);
        add(b[i],1);
    }
    cout << ans;
}