POJ 2299 Ultra-QuickSort 离散化加树状数组求逆序对

http://poj.org/problem?id=2299

题意:求逆序对

题解:用树状数组。每读入一个数x,另a[x]=1.那么a数列的前缀和s[x]即为x前面(或者说,再x之前读入)小于x的个数,而逆序对就是x前面所有的数减去s[x]

  关于离散化,由于5e5个数据是1e9范围的整数,上面的数组明显无法开到1e9,所以有一个离散化处理技巧:将每个数的下标记录下来,然后对原序列排序(下标也跟着排)。于是我们得到了一个下标的逆序对,观察发现其值等于原数列的逆序对。

ac代码:

坑:忘记初始化树状数组了。。。疯狂初始化别的数组orz

#define _CRT_SECURE_NO_WARNINGS
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<iomanip>
#include<cmath>
#include<cstdio>
#include<string>
#include<climits>
#include<stack>
#include<ctime>
#include<list>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<sstream>
#include<fstream>
#include<iostream>
#include<functional>
#include<algorithm>
#include<memory.h>
//#define INF LONG_MAX
#define eps 1e-6
#define pi acos(-1.0)
#define e exp(1.0)
#define rep(i,t,n) for(int i =(t);i<=(n);++i)
#define per(i,n,t) for(int i =(n);i>=(t);--i)
#define mp make_pair
#define pb push_back
#define mmm(a,b) memset(a,b,sizeof(a))
//std::ios::sync_with_stdio(false);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
void smain();
#define ONLINE_JUDGE
int main() {
//ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("C:\\Users\\SuuTT\\Desktop\\test\\in.txt", "r", stdin);
freopen("C:\\Users\\SuuTT\\Desktop\\test\\out.txt", "w", stdout);
//ifstream in;
//string filename;
//getline(cin, filename,'\n');
//in.open(filename); long _begin_time = clock();
#endif
smain();
#ifndef ONLINE_JUDGE
long _end_time = clock();
printf("time = %ld ms.", _end_time - _begin_time);
#endif
return ;
}
int dir[][] = { ,,,,-,,,- };
const int maxn = 5e5 + ;
int n, m;
ll a[maxn];
pair<int, int> aa[maxn];
int d[maxn];
int level[maxn];
int lowbit(int x) { return x & (-x); }
void add(int x, int v) {//a[x]+=v;
while (x <= maxn) {
d[x] += v;
x += lowbit(x);
} }
int query(int x) {
int res = ;
while (x) {
res += d[x];
x -= lowbit(x);
}
return res;
}
struct node { int x, y;
node(int x = , int y = ) :x(x), y(y) {} }; void Run() { } void smain() {
while (cin >> n){
if (!n)return; mmm(d, );
rep(i, , n) { scanf("%d", &aa[i].first);
aa[i].second = i;
}
sort(aa+, aa + n+);
rep(i, , n)a[i] = aa[i].second;//a[aa[i].second]=i; ll ans = ;
rep(i, , n) {
add(a[i], );
ans += (i - query(a[i])); }
cout << ans << endl;
} }
上一篇:codevs 4163 求逆序对的数目 -树状数组法


下一篇:51 Nod 1107 斜率小于0的连线数量 (转换为归并求逆序数或者直接树状数组,超级详细题解!!!)