線段樹求逆序對
阿新 • • 發佈:2018-03-21
std con pac clu can -m cnblogs amp ons
- 思路:
離散化變成一個1-n的數組表示每個數的排名,然後按順序插入各個數排名,並且查詢比它排名大的數的個數。
這個離散化方法還是比較好的,思維難度和代碼難度都比較小。
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <iostream> using namespace std; const int maxn=40005; struct Node{ int data,rank,index; }num[maxn]; int n,sum[maxn<<2]; int t,L,R; inline bool cmp1(const Node & a,const Node & b) { return a.data<b.data; } inline bool cmp2(const Node & a,const Node & b) { return a.index<b.index; } void add(int now,int l,int r) { if(l==r) { sum[now]++; return ; } int mid=(l+r)>>1; if(t<=mid)add(now<<1,l,mid); else add(now<<1|1,mid+1,r); sum[now]=sum[now<<1]+sum[now<<1|1]; return ; } int query(int now,int l,int r) { if(L<=l&&r<=R) { return sum[now]; } int mid=(l+r)>>1; int ans=0; if(L<=mid)ans+=query(now<<1,l,mid); if(mid<R)ans+=query(now<<1|1,mid+1,r); return ans; } int main() { int n,anss=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&num[i].data); num[i].index=i; } sort(num+1,num+1+n,cmp1);//離散化開始 for(int i=1;i<=n;i++)num[i].rank=i; sort(num+1,num+1+n,cmp2); for(int i=1;i<=n;i++) { t=num[i].rank,L=t+1,R=n; add(1,1,n); anss+=query(1,1,n); } cout<<anss<<endl; return 0; }
線段樹求逆序對