逆序对 线段树解法

Posted struct Edge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逆序对 线段树解法相关的知识,希望对你有一定的参考价值。

逆序对 【线段树解法】

求逆序对问题是一个十分经典的算法问题,通常使用归并排序解决,经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 }

 

以上是关于逆序对 线段树解法的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ2212 [Poi2011]Tree Rotations 线段树合并 逆序对

线段树求逆序对

CCPC河南省赛B-树上逆序对| 离线处理|树状数组 + 线段树维护逆序对 + dfs序 + 离散化

权值线段树2

权值线段树求逆序对问题

逆序对的三种求法(归并排序,树状数组,线段树)