51nod 1019 逆序數
阿新 • • 發佈:2017-08-09
序列 lowbit define class algo ash def sam out
在一個排列中,如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麽它們就稱為一個逆序。一個排列中逆序的總數就稱為這個排列的逆序數。
如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序數是4。給出一個整數序列,求該序列的逆序數。Input第1行:N,N為序列的長度(n <= 50000)
第2 - N + 1行:序列中的元素(0 <= Aii <= 10^9)Output輸出逆序數Sample Input
4 2 4 3 1
Sample Output
4
逆序數如上所述,就是一對數的前後位置與大小順序相反,即前面的數大於後面的數,這個東西裏離散還會講的,
這道題需要先離散數據,要不TLE的
樹狀數組的代碼如下
#include <stdio.h> #include <algorithm> using namespace std; const int N = 500005; struct Node { int val; int pos; friend bool operator <(Node a,Node b) { return a.val < b.val; } }; Node node[N]; int c[N], hash[N], n; int lowbit(intx) { return x & (-x); } void update(int x) { while (x <= n) { c[x] += 1; x += lowbit(x); } } int getsum(int x) { int sum = 0; while (x > 0) { sum += c[x]; x -= lowbit(x); } return sum; }
int main() { scanf("%d", &n);for (int i = 1; i <= n; ++i) { scanf("%d", &node[i].val); node[i].pos = i; } sort(node + 1, node + n + 1); for (int i = 1; i <= n; ++i) hash[node[i].pos] = i; int ans = 0; for (int i = 1; i <= n; ++i) { update(hash[i]); ans += i - getsum(hash[i]); } printf("%d\n", ans); return 0; }
TLE的代碼
#include <bits/stdc++.h> using namespace std; #define N 500005 int c[N]; int n; int lowbit(int i) { return i&(-i); } int insert(int i,int x) { while(i<=n) { c[i]+=x; i+=lowbit(i); } return 0; } int getsum(int i) { int sum=0; while(i>0) { sum+=c[i]; i-=lowbit(i); } return sum; }int main() { while(cin>>n) { int ans=0; memset(c,0,sizeof(c)); for(int i=1; i<=n; i++) { int a; cin>>a; insert(a,1); ans+=i-getsum(a); } cout<<ans<<endl; } return 0; }
51nod 1019 逆序數