1. 程式人生 > >[機房練習賽] 題解 求逆序對

[機房練習賽] 題解 求逆序對

大家都很強, 可與之共勉。

如果你有一個長度為n 的序列:
a1; a2; a3; : : : ; an
那麼它的一個逆序對是一個二元組:< i; j > 滿足i < j 且ai > aj,其中i; j 2 [1; n]。
我們稱一個序列所包含的逆序對的個數為這個序列的逆序對數。
那麼問題來了:
我給出一個長度為n 的序列,需要你計算:
a1; a2 : : : an-1; an
a2; a3 : : : an; a1
a3; a4 : : : a1; a2

an; a1 : : : an-2; an-1
這n 個序列的逆序對之和。
Input
輸入檔案包含2 行:
第1 行1 個整數:n,表示給定序列的長度。
第2 行n 個整數:a1 a2 : : : an,表示初始序列。
Output
輸出n 個序列的逆序對的和。
Sample
rotinv.in
3
2 2 3
rotinv.out
6
以上樣例中,3 個序列分別是:2 2 3,2 3 2,3 2 2,分別有0,1,2 個逆序對,所以和為6。
rotinv.in
3
1 1 1
rotinv.out
0
以上樣例中,3 個序列都是:1 1 1,逆序對數為0,所以答案為0。
Note
• 對於30% 的資料,1 n 300
• 對於60% 的資料,1 n 5000
• 對於100% 的資料,1 n 106,1 ai n

#include "cctype"
#include "cstdio"
#include "cstring"
#include "algorithm"

#define lowbit(x)  ((x) & (-x))
#define abs(a)  ((a) < 0 ? (-(a)) : (a))
#define max(a, b)  ((a) > (b) ? (a) : (b))
#define min(a, b)  ((a) < (b) ? (a) : (b))

#define rep(_, m, n)  for(register int _ = (m); i <= (n); ++i)
#define res(_, n, m) for(register int _ = (n); i >= (m); --i) #define edges(u) for(register int _ = head[u]; _; _ = g[i].pre) template <class T> inline bool readIn( T &x ) { char ch; T opt = 1; while( !isdigit(ch = (char) getchar()) && (ch ^ -1) ) if( ch == '-'
) opt = -1; if( !(ch ^ -1) ) return false; for( x = ch - 48; isdigit(ch = (char) getchar()); x = (x << 1) + (x << 3) + ch - 48 ); x *= opt; return true; } template <class T> inline void write( T x ) { if( x > 9 ) write(x / 10); putchar( x % 10 + 48 ); } template <class T> inline bool writeIn( T x ) { if(x < 0) { x = -x; putchar('-'); } write(x); return true; } class io { public: #define SIM "rotinv" io() { freopen(SIM ".in", "r", stdin); freopen(SIM ".out", "w", stdout); } ~io() { fclose(stdin); fclose(stdout); } } WhiteBunny; typedef long long LL; const int MAXN = (int) 1e6 + 5; int n, bit[MAXN], a[MAXN]; LL ans, cnt; inline bool modify(int pos, int delta) { for(register int i = pos; i <= n; i += lowbit(i)) bit[i] += delta; } inline LL query(int r) { int rt = 0; for(register int i = r; i; i -= lowbit(i)) rt += bit[i]; return rt; } int main() { readIn(n); rep(i, 1, n) readIn(a[i]); rep(i, 1, n) { cnt += (i - 1) - query(a[i]); modify(a[i], 1); } rep(i, 1, n) { modify(a[i], -1); cnt += (n - 1) - query(a[i]); cnt -= query(a[i] - 1); modify(a[i], 1); ans += cnt; } writeIn(ans); putchar(10); return 0; }

程式碼騷起來

#include "cctype"
#include "cstdio"
#include "cstring"
#include "algorithm"

#define lowbit(x)  ((x) & (-x))
#define abs(a)  ((a) < 0 ? (-(a)) : (a))
#define max(a, b)  ((a) > (b) ? (a) : (b))
#define min(a, b)  ((a) < (b) ? (a) : (b))

#define rep(_, m, n)  for(register int _ = (m); i <= (n); ++i)
#define res(_, n, m)  for(register int _ = (n); i >= (m); --i)
#define edges(u)  for(register int _ = head[u]; _; _ = g[i].pre)

template <class T>
inline bool readIn( T &x )  {
    char ch;
    T opt = 1;
    while( !isdigit(ch = (char) getchar()) && (ch ^ -1) )  if( ch == '-' )  opt = -1;
    if( !(ch ^ -1) )  return false;
    for( x = ch - 48; isdigit(ch = (char) getchar()); x = (x << 1) + (x << 3) + ch - 48 );
    x *= opt;
    return true;
}

template <class T>
inline void write( T x )  {
    if( x > 9 )
        write(x / 10);
    putchar( x % 10 + 48 );
}

template <class T>
inline bool writeIn( T x )  {
    if(x < 0)  {
        x = -x;
        putchar('-');
    }
    write(x);
    return  true;
}

class io  {
public:
    #define SIM "rotinv"
    io()  {
        freopen(SIM ".in", "r", stdin);
        freopen(SIM ".out", "w", stdout);
    }
    ~io()  {
        fclose(stdin);
        fclose(stdout);
    }
} WhiteBunny;

typedef long long LL;

const int MAXN = (int) 1e6 + 1;

int n, bit[MAXN], a[MAXN];
LL ans, cnt;

inline bool modify(int pos, int delta)  {
    for(register int i = pos; i <= n; i += lowbit(i))
        bit[i] += delta;
}

inline int query(int r)  {
    int rt = 0;
    for(register int i = r; i; i -= lowbit(i))
        rt += bit[i];
    return rt;  
}

int main()  {
    readIn(n);
    rep(i, 1, n)  readIn(a[i]), cnt += (i - 1) - query(a[i]), modify(a[i], 1);  
    rep(i, 1, n)
        modify(a[i], -1),  (cnt += (n - 1) - query(a[i])) -= query(a[i] - 1),
        modify(a[i], 1),  ans += cnt;
    writeIn(ans);
    putchar(10);
    return 0;
}