離散化及樹狀陣列求逆序對
阿新 • • 發佈:2018-11-02
用樹狀陣列求逆序對的時候注意:要統計b[i]-1的字首和,因為可能有相同值的元素
不去重離散化:
sort(a+1, a+n+1, cmp);
for(int i=1; i<=n; i++) {
if(i == 1 || a[i].val != a[i-1].val) {
tot++;
}
b[a[i].ord] = tot;
}
去重離散化,和不去重差不多,只不過是放到一個新數組裡面,並且維護去重後有多少個元素,然後對新陣列按輸入順序再排個序就可以了
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int MAXN = 500000 + 10; long long n,tree[MAXN],ans,tot,b[MAXN]; struct node{ long long ord,val; }a[MAXN]; void add(long long p, long long x) { while(p <= n) { tree[p] += x; p += (p&-p); } } int getsum(long long p) { long long sum = 0; while(p) { sum += tree[p]; p -= (p&-p); } return sum; } bool cmp(node x, node y) { return x.val < y.val; } int main() { scanf("%lld", &n); for(int i=1; i<=n; i++) { scanf("%lld", &a[i].val); a[i].ord = i; } sort(a+1, a+n+1, cmp); for(int i=1; i<=n; i++) { if(i == 1 || a[i].val != a[i-1].val) { tot++; } b[a[i].ord] = tot; } for(int i=n; i; i--) { ans += getsum(b[i]-1); add(b[i], 1); } printf("%lld", ans); return 0; }