求逆序對(歸併排序/樹狀陣列)
阿新 • • 發佈:2019-01-01
兩種演算法的時間複雜度都是:O(nlogn)
但是,有可能樹狀陣列需要離散化!
所以,由許多元素共同影響下,歸併排序求逆序對 比 樹狀陣列求逆序對
快
歸併排序:
#include <bits/stdc++.h> #define ll long long #define N 100005 using namespace std; int a[N],tmp[N]; ll ans; int n; inline void merge(int l,int m,int r) { int i = l; int j = m + 1; int k = l; while(i <= m && j <= r) { if(a[i] > a[j]) { tmp[k++] = a[j++]; ans += m - i + 1; } else { tmp[k++] = a[i++]; } } while(i <= m) tmp[k++] = a[i++]; while(j <= r) tmp[k++] = a[j++]; for(int i=l;i<=r;i++) a[i]=tmp[i]; } void merge_sort(int l,int r) { int mid=(l+r)/2; if(l<r) { merge_sort(l,mid); merge_sort(mid+1,r); merge(l,mid,r); } } int main() { scanf("%d",&n); for(int i = 1;i <= n;++i) { scanf("%d",&a[i]); } merge_sort(1,n); printf("%lld",ans); return 0; }
樹狀陣列:
//樹狀陣列 求逆序對 //找了好久,發現多取了一個mod #include <cstdio> #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <map> #include <cstdlib> #define ll long long #define N 500005 using namespace std; const int mod=99999997; int n; ll c[N]; int lowbit(int x) { return x&(-x); } void add(int u,int v) { if(!u)return ; while(u<=n) { c[u]+=v; u+=lowbit(u); } } ll query(int y) { if(!y)return 0; ll ans=0; while(y>0) { ans+=c[y]; y-=lowbit(y); } return ans; } struct node { int num; int val; }a[N]; ll seq[N]; int cmp(node x,node y) { return x.val<y.val; } int main() { scanf("%d",&n); for (int i = 1;i <= n;i++) { scanf("%d",&a[i].val); a[i].num=i; } sort(a+1,a+1+n,cmp); int tt=0; for (int i = 1;i <= n;i++) //離散化 { if(a[i].val==a[i-1].val) //注意 相等 { seq[a[i].num]=tt; continue; } seq[a[i].num]=++tt; } ll cnt=0; for(int i = 1;i <= n;i++) { add(seq[i],1); cnt+=(i-query(seq[i])); } printf("%lld\n",cnt); return 0 ; }