求逆序对的解法
一、归并排序解法
#include <bits/stdc++.h> using namespace std; int n,a[2000001],temp[2000001]; long long ans; void msort(int L,int R) { int mid = (L + R) / 2; if(R > L) { msort(L,mid); msort(mid+1,R); int i = L,k = L,j = mid + 1; while(i<=mid && j<=R) { if(a[i] > a[j]) { temp[k++] = a[j++]; ans += mid - i + 1; } else temp[k++] = a[i++]; } while(i<=mid) temp[k++] = a[i++]; while(j<=R) temp[k++] = a[j++]; for(int x = L;x<=R;x++) a[x] = temp[x]; } } int main() { cin>>n; for(int i = 0;i<n;i++) cin>>a[i]; msort(0,n-1); cout<<ans<<endl; return 0; }
这是求小的个数的树状数组做法:
#include <cstdio> #include <cstring> const int maxn = 100010; #define lowbit(i) ((i)&(-i)) int c[maxn]; void update(int x, int v) { for(int i = x;i < maxn; i += lowbit(i)) c[i] += v; } int getSum(int x) { int sum = 0; for(int i = x;i>0;i -= lowbit(i)) sum += c[i]; return sum; } int main() { int n,x,ans = 0; scanf("%d",&n); memset(c,0,sizeof(c)); for(int i = 0;i<n;i++) { scanf("%d",&x); update(x,1); printf("%d\n",getSum(x-1)); } }
树状数组正解解法:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<vector> #include<map> #include<string> #include<cstring> #define int long long int #define lowbit(x) x & -x const int N=5e5+10; using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int ans; int tree[N],n,a[N],b[N]; void add(int x) { while(x<=n) { tree[x]++; x+=lowbit(x); } } int query(int x) { int ans=0; while(x>0) { ans+=tree[x]; x-=lowbit(x); } return ans; } signed main() { n=read(); for(int i=1;i<=n;++i) a[i]=read(),b[i]=a[i]; sort(a+1,a+1+n); int len=unique(a+1,a+1+n)-a-1; for(int i=1;i<=n;++i) { int p=lower_bound(a+1,a+1+len,b[i])-a; add(p); ans+=i-query(p); } cout<<ans; return 0; }