POJ

来源:互联网 发布:大富翁数据库 编辑:程序博客网 时间:2024/06/08 00:44

利用树状数组求逆序数,但是数据范围比较大,要使用离散化坐标

参考:http://blog.csdn.net/guhaiteng/article/details/52138756


// 树状数组求逆序数 + 离散化#include <cstdio>#include <string>#include <algorithm>#define MAX 500000 + 10using namespace std;typedef long long LL;typedef struct {    LL val;    LL pos;} Node;Node node[MAX];LL c[MAX];LL bit[MAX];LL lowbit( LL i ) {    return i & ( -i );}void update( LL i, LL x, LL n ) {    while( i <= n ) {        bit[i] = bit[i] + x;        i = i + lowbit( i );    }}LL getSum( LL i ) {    LL ans = 0;    while( i > 0 ) {        ans = ans + bit[i];        i = i - lowbit( i );    }    return ans;}bool cmp( Node a, Node b ) {    return a.val < b.val ? 1 : 0;}int main() {    LL n;    while( scanf( "%lld", &n ) != EOF ) {        if( n == 0 ) break;        for( LL i = 1; i <= n; i++ ) {            scanf( "%lld", &node[i].val );            node[i].pos = i;        }        sort( node + 1, node + 1 + n, cmp );        for( LL i = 1; i <= n; i++ ) {  // 离散化            c[node[i].pos] = i;        }        // 初始化树状数组        for( LL i = 1; i <= n; i++ ) bit[i] = 0;        LL ans = 0;        for( int i = 1; i <= n; i++ ) {            update( c[i], 1, n );            ans = ans + i - getSum( c[i] );        }        printf( "%lld\n", ans );    }    return 0;}


0 0
原创粉丝点击