poj 2299 Ultra-QuickSort(fenwick树求逆序对)
2014-10-09 15:08
197 查看
树状数组求逆序对数方法 GET!
题意很直白:求一个长度为n的序列a1,a2,a3...an的逆序对数,其中aj在区间[0, 999 999 999]内。
假设一个数组x, x[aj]表示aj存不存在。
数组c是x的fenwick树, 将序列元素依次插入c。
如果当前插入aj,sum(aj)表示已经插入的前j个数中,小于等于aj的数的个数
,逆序对增加j-sum(aj)
所以先清空c,然后依次插入,累加答案。
但注意到aj的区间很大,所以先离散化一下。
题意很直白:求一个长度为n的序列a1,a2,a3...an的逆序对数,其中aj在区间[0, 999 999 999]内。
假设一个数组x, x[aj]表示aj存不存在。
数组c是x的fenwick树, 将序列元素依次插入c。
如果当前插入aj,sum(aj)表示已经插入的前j个数中,小于等于aj的数的个数
,逆序对增加j-sum(aj)
所以先清空c,然后依次插入,累加答案。
但注意到aj的区间很大,所以先离散化一下。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #include <queue> #include <stack> #include <cassert> #include <algorithm> #include <cmath> #include <set> #include <list> #include <map> #include <limits> using namespace std; #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define REP(i, s, t) for(int (i)=(s);(i)<=(t);++(i)) #define UREP(i, s, t) for(int (i)=(s);(i)>=(t);--(i)) #define REPOK(i, s, t, o) for(int (i)=(s);(i)<=(t) && (o);++(i)) #define MAXN 500000 #define MAXM 10000 #define MOD 10000007 #define PI 3.1415926535897932384626433832795 #define HALF_PI 1.5707963267948966192313216916398 typedef long long LL; typedef vector<int> veci; typedef vector<pair<int, int> > vect; typedef pair<int, int> pairi; const double maxdouble = numeric_limits<double>::max(); const double eps = 1e-10; const int INF = 0x7FFFFFFF; struct node{ int val; int pos; }; node arr[MAXN+5]; int re[MAXN+5]; int c[MAXN + 5]; int n; /* struct comp_obj{ bool operator() (const node & lhs, const node & rhs) { return lhs.val < rhs.val; } };*/ bool comp(const node & lhs, const node & rhs) { return lhs.val < rhs.val; } int lowbit(int x) { return x&(-x); }; int sum(int x) { int ret = 0; while(x > 0) { ret += c[x]; x -= lowbit(x); } return ret; } void update(int x) { while(x <= n) { c[x] += 1; x += lowbit(x); } } int main() { //freopen("input.in", "r", stdin); while(scanf("%d",&n) == 1 && n) { REP(i, 1, n) { scanf("%d", &arr[i].val); arr[i].pos = i; } sort(arr+1, arr+n+1, comp); REP(i, 1, n) { re[arr[i].pos] = i; } REP(i, 0, n) c[i] = 0; LL ans = 0; REP(i, 1, n) { update(re[i]); ans += i - sum(re[i]); } cout << ans << endl; } return 0; }
相关文章推荐
- poj 2299 Ultra-QuickSort(归并排序求逆序对)
- POJ 2299 Ultra-QuickSort(逆序对数,线段树/树状数组/归并排序)
- POJ - 2299 Ultra-QuickSort —— 逆序对
- poj_2299 Ultra-QuickSort(归并排序/树状数组 求逆序对)
- poj 2299 Ultra-QuickSort(逆序对)
- poj2299 Ultra-QuickSort--求逆序对+树状数组
- poj 2299 Ultra-QuickSort 归并排序求解逆序对
- POJ 2299 Ultra-QuickSort (求序列的逆序对数)
- POJ 2299 Ultra-QuickSort (树状数组求逆序数+离散化)
- poj 2299 Ultra-QuickSort(求逆序数,树状数组)
- POJ2299 Ultra-QuickSort(树状数组求逆序数+离散化)
- POJ2299 Ultra-QuickSort【树状数组】【逆序数】
- poj 2299 Ultra-QuickSort 【线段树 or 线段树+lazy or 树状数组 or 归并排序】 求逆序对
- Poj 2299 Ultra-QuickSort 求逆序数 4种方法总结
- POJ 2299 Ultra-QuickSort 【归并排序求逆序对数】
- 【原】 POJ 2299 Ultra-QuickSort 逆序数 解题报告
- poj 2299 Ultra-QuickSort【归并排序求逆序数】
- poj 2299 Ultra-QuickSort(求逆序数,树状数组)
- POJ[2299]Ultra-QuickSort 逆序对:线段树||树状数组||分治
- 【POJ】2299 Ultra-QuickSort(逆序对)