本文共 2350 字,大约阅读时间需要 7 分钟。
第1行:N,N为序列的长度(n <= 50000)第2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9)
输出逆序数
42431
4
#include#define maxsize 50010long long int count = 0;int a[maxsize],temp[maxsize]; void merge(int s,int m,int e) { int p1 = s,p2 = m+1,p = 0; while(p1 <= m && p2 <= e) { if(a[p1]<=a[p2]) temp[p++]=a[p1++]; else { temp[p++]=a[p2++]; count += m-p1+1; } } while(p1<=m) temp[p++]=a[p1++]; while(p2<=e) temp[p++]=a[p2++]; int i; for(i = 0;i < p; ++i) a[s+i] = temp[i]; } void mergesort(int l,int r) { if(l
树状数组求逆序原理:
#includeusing namespace std;const int MAXN = 50005;int C[MAXN];int a[MAXN];int n;struct Node{ int d,ord;//数据与 位置 bool operator<(const Node o)const{ return d < o.d; }}p[MAXN];int lowBit(int i){ return i&(-i);}int add(int i,int x){ while(i <= n){ C[i] += x; i += lowBit(i); }}int getSum(int i){ int sum = 0; while(i){ sum += C[i]; i -= lowBit(i); } return sum;}int main() { scanf("%d",&n); memset(C,0,sizeof(C)); for(int i = 1; i <= n; ++i){//从1开始 scanf("%d",&p[i].d); p[i].ord = i; } sort(p+1,p+n+1);//按照数据大小 从小到大排序 //数据被离散化为从1开始的数 for(int i = 1; i <= n; ++i){ a[p[i].ord] = i; } int ans = 0; for(int i = 1; i <= n; ++i){ add(a[i],1);//a[i]表示新的数据 ans += i - getSum(a[i]); //这里 i可以用getSum(n)代替 i表示当前共有多少数 减去比a[i]小的数 } printf("%d\n",ans); return 0; }
原因:0&0 == 0 此时无法实现i的更新 会进入死循环(add中的while)
#includeusing namespace std;const int MAXN = 50000;int C[MAXN];int n;int lowBit(int i){ return i&(-i);}int add(int i, int x){ while(i <= n){ C[i] += x; i += lowBit(i); }}int getSum(int i){ int sum = 0; while(i > 0){ sum += C[i]; i -= lowBit(i); } return sum;}int main() { memset(C,0,sizeof(C)); scanf("%d",&n); int x; int ans = 0; for(int i = 1; i <= n; ++i){ scanf("%d",&x); add(x,1); ans += i - getSum(x); } printf("%d\n",ans);// for(int i = 1; i <= n; ++i){// printf("%d ",C[i]);// } //cout << getSum(5)-getSum(3); return 0; }
转载地址:http://neimi.baihongyu.com/