首页 > 代码库 > 逆序对 【线段树解法】

逆序对 【线段树解法】

逆序对 【线段树解法】

求逆序对问题是一个十分经典的算法问题,通常使用归并排序解决,经gster大神指点,写出了逆序对线段树写法,顺便练了练线段树。

题目传送门:http://noi.openjudge.cn/ch0204/7622/

代码:

 1 /*  2         Segment_Tree  3         author: SHHHS 4         2016-09-28 12:35:17  5 */  6 #include "bits/stdc++.h" 7  8 using namespace std ; 9 typedef long long QAQ ;10 const int maxN = 100100 ;11 struct SegTree { int l , r , sum ;};12 13 SegTree tr[ maxN<<2 ] ;14 int arr[ maxN ] ;15 void Build_Tree ( int x , int y , int i ) {16          tr[ i ].l = x ; tr[ i ].r = y ;17          if ( x==y ) return ;18          else {19                   QAQ mid = ( tr[ i ].l + tr[ i ].r ) >> 1 ;20                  Build_Tree ( x , mid , i<<1 ) ;21                  Build_Tree ( mid +1 , y , i<<1|1 ) ;22          }23 }24 25 void Insert_Tree ( int q , int i ) {26          if ( q==tr[ i ].l && q==tr[ i ].r ) {27                    tr[ i ].sum ++ ;28                    return ;29          }30          else {31                    QAQ mid = ( tr[ i ].l + tr[ i ].r ) >> 1 ;32                    if ( q>mid ) Insert_Tree ( q , i<<1|1 ) ;33                    else if ( q<=mid ) Insert_Tree ( q , i<<1 ) ;34          }35          tr[ i ].sum = tr[ i<<1 ].sum + tr[ i<<1|1 ].sum ;36 }37 38 QAQ Query_Tree (  int q , int w , int i ){39          if ( q<=tr[i].l && w>=tr[i].r ) {40                   return tr[i].sum ;41          }42          else {43                   QAQ mid=(tr[i].l+tr[i].r)>>1;44                   if ( q>mid )return Query_Tree(q,w,i<<1|1);45                   else if ( w<=mid )return Query_Tree(q,w,i<<1);46                   else return Query_Tree(q,mid,i<<1) + Query_Tree(mid+1,w,i<<1|1);47         48          }49 }50 51 int main ( ) {52          int N ; 53          QAQ ans = 0;54          scanf ("%d",&N);55          for ( int i=1 ; i<=N ; ++i ) scanf ( "%d" , arr + i ) ;56          Build_Tree ( 1 , N , 1 ) ;57          for ( int i=1 ; i<=N ; ++i ) {58                   int temp = arr [ i ] ;59                   Insert_Tree ( temp , 1 ) ;60                   ans += i - Query_Tree ( 1 , temp , 1 ) ;61          }62          printf ( "%lld" , ans ) ;63          return 0 ;64 }

 

逆序对 【线段树解法】