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,' '); //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 0; } int dir[4][2] = { 1,0,0,1,-1,0,0,-1 }; const int maxn = 5e5 + 5; 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 = 0; while (x) { res += d[x]; x -= lowbit(x); } return res; } struct node { int x, y; node(int x = 0, int y = 0) :x(x), y(y) {} }; void Run() { } void smain() { while (cin >> n){ if (!n)return; mmm(d, 0); rep(i, 1, n) { scanf("%d", &aa[i].first); aa[i].second = i; } sort(aa+1, aa + n+1); rep(i, 1, n)a[i] = aa[i].second;//a[aa[i].second]=i; ll ans = 0; rep(i, 1, n) { add(a[i], 1); ans += (i - query(a[i])); } cout << ans << endl; } }