码迷,mamicode.com
首页 > 其他好文 > 详细

逆序对 【线段树解法】

时间:2016-09-29 01:51:04      阅读:107      评论:0      收藏:0      [点我收藏+]

标签:

逆序对 【线段树解法】

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

 

逆序对 【线段树解法】

标签:

原文地址:http://www.cnblogs.com/shadowland/p/5918222.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!