무한 바꿈 (펜윅 트리 + 이산)

아이디어와 코드 참조 : https://blog.csdn.net/u014800748/article/details/45420085

증가하는 순서로 모든 양의 정수로 구성되는 무한 시퀀스가있다 :  P  = {1, 2, 3, ...}. 우리는 수행  N  이 순서로 스왑 작업을. 스왑 ( A는 ,  B )의 위치에 시퀀스의 요소를 교환하는 동작이다  및  B를 . 당신의 작업은 인덱스 쌍의 수 즉, 결과 순서 반전의 수를 찾을 수 있습니다  ( I ,  J 것을)  나는  <  J  와  P  >  P는 J를 .

입력

첫 번째 라인은 하나의 정수 포함  N  ( 1 ≤  N  ≤ 10 (5) 의 수 -)  시퀀스를인가 swapoperations.

다음의 각  N 개의  행은 두 정수 포함  I  및  B I  ( ≤ 1  I ,  b를 내가  10 ≤ 9I  ≠  B I 의 인자 -)  스왑 동작.

산출

결과 순서 반전의 수 - 하나의 정수를 인쇄합니다.

입력
2 
4 2
1 4
산출
4
입력
3 
1 6
3 4
2 5
산출
(15)

노트

다음 첫 번째 샘플에서, 서열은 변형되고된다  . 그것은 인덱스 쌍에 의해 형성된 4 역전 갖는  (1, 4),  (2, 3),  (2, 4),  (3, 4).

코드 :

#INCLUDE <cstdio> 
#INCLUDE <iostream> 
#INCLUDE <CString을> 
#INCLUDE <알고리즘> 
#INCLUDE <큐> 
#INCLUDE <적층> 
#INCLUDE < 설정 > 
#INCLUDE <벡터> 
#INCLUDE <cmath>
 CONST의  INT maxn = + 2E5 (5) ; 
타입 정의  LL;
사용하는  네임 스페이스 표준을; 

LL S [maxn, 합계 [maxn]; 
INT의 SS [maxn];
int로 A [maxn], B [maxn를, POS [maxn];
INT lowbit ( INT X) 
{ 
    X는 (- X); 
} 
int로 N;
보이드 업데이트 ( INT의 POS, INT의 AD) 
{ 
    동안 (POS <= maxn) 
    { 
        S [pos가] + = 광고; 
        POS + = lowbit (POS); 
    } 
} 
LL getnum ( INT의 POS) 
{ 
    LL 입술 = 0 ;
    반면 POS (> 0 ) 
    { 
        입술 + = S [POS]; 
        POS - = lowbit (POS); 
    } 
    반환 입술을; 
}
INT 의 main () 
{ 
    INT의 N;
    동안 (~는 scanf ( " %의 D ' , N)) 
    { 
        위해 ( int로 난 = 1 ; i가 N = <; 내가 ++ ) 
        { 
            는 scanf ( " % d 개 %의 D ' , A [I], B [I])를 ; 
            SS는 [내가] = A [I]; 
            SS [내가 = 않음 +] [i]는 B 단계; 
            POS [I] = I; 
            POS [나 N을 +] = 난 + N을; 
        } 
        종류 (SS + 1 , SS +2 * N + 1 ); 
        SS [ 0 ] = 0 ;
        INT CNT = 0 ;
        위한 ( int로 I = 1 ; i가 <= 2 * N; I ++ )
         경우 (I의 == 1 개 || SS [I] = SS [I! - 1 ]) 
            SS [ ++ CNT = SS [I]; 
        합 [ 0 ] = 0 ;
        위한 ( int로 I = 1 ; i가 CNT를 <=, 내가 ++ ) 
            합계 [I] = 합계 [I - 1] + SS [I] - SS [I - 1 ] - 1 ;
        위한 ( int로 난 = 1 ; i가 N = <; 내가 ++ ) 
        { 
            INT의 AA = LOWER_BOUND (SS + 1 , + SS CNT + 1 , A [I]) - SS;
            INT BB = LOWER_BOUND (SS + 1 , + SS CNT + 1 , [I] b) - SS; 
            스왑 (POS [AA] POS [BB]); 
        } 
        memset 함수 (S, 0 , sizeof 연산자 (S)); 
        LL ANS = 0 ;
        대한 ( INTI = CNT; 나는; 난 - ) 
        { 
            ANS + = getnum POS ([I]); 
            ANS + = ABS (합 [I]는 - 합 [POS [I]); 
            업데이트 (POS [I], 1 ); 
        } 
        의 printf ( " % LLD \ 없음 " , ANS); 
    } 

   반환  0 ; 
}

 

추천

출처www.cnblogs.com/Staceyacm/p/11312245.html