By
yusijia
Updated:
题目:
http://poj.org/problem?id=2299
注意: 树状数组下标要从1开始
分析:
例如 :
pos:1 2 3 4 5
val: 9 1 0 5 4
离散化:
将上面的val变为5 2 1 4 3 离散后的数据
输入的顺序为1 2 3 4 5 reflect数组的下标
sort(node + 1, node + 1 + n, cmp);
val: 0 1 4 5 9
pos: 3 2 5 4 1
val离散成下标1 2 3 4 5
就成了:1的输入顺序是3,2的输入顺序是2,3的输入顺序是5,4的输入顺序是4,5的输入顺序是1
reflect[node[i].pos] = i;
reflect下标: 1 2 3 4 5
离散后的数据:5 2 1 4 3 (按输入的顺序)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std;
const int N = 500005;
struct Node{ int val; int pos; };
Node node[N]; int n; int tree[N], reflect[N];
bool cmp(const Node &a, const Node &b) { return a.val < b.val; }
int lowbit(int x) { return x & -x; }
void update(int index, int val) { while(index <= n){ tree[index] += val; index += lowbit(index); } }
int getsum(int index) { int sum = 0; while(index > 0){ sum += tree[index]; index -= lowbit(index); } return sum; }
int main() { while(scanf("%d", &n) != EOF && n){ for(int i = 1; i <= n; i++){ scanf("%d", &node[i].val); node[i].pos = i; } sort(node + 1, node + 1 + n, cmp); for(int i = 1; i <= n; i++){ reflect[node[i].pos] = i; } for(int i = 1; i <= n; i++) tree[i] = 0; long long ans = 0; for(int i = 1; i <= n; i++){ update(reflect[i], 1); ans += i - getsum(reflect[i]); } printf("%lld\n", ans); } return 0; }
|