to help you give some (n) the number of disorderly order , let you ask the number of times a bubble sort needs to be exchanged (n<=500000)
Obviously can't directly simulate the bubble sort, in fact the number of exchanges is the sequence of the reverse logarithm.
Because the data range is 0≤a[i]≤999,999,999, we need to discretization first, and then use the appropriate data results to find out the reverse order
You can add the a[i] step-by-step with a segment tree, and add as many as you like before adding a query.
Also available as a tree array, because the tree array is asked for (1...x) the number and so each time before adding a query I-sum (A[i]) can be
Tree-like array:
5620k688ms#include<cstdio> #include <algorithm> #include <iostream> #include <cstring> using namespace std; #define LL Long Long#define lowbit (x) (x&-x) const int M=5e5+100;int num[m];int Hash[m];int tree[m] ; The tree array int n;int Bin (int val)//two divides the discrete ordinal number {int l=0,r=n-1; while (r>=l) {int m= (L+R) >>1; if (hash[m]==val) return m+1; if (hash[m]>val) r = m-1; else l=m+1; }}void Add (int rt,int x) {while (rt<=m-1) {tree[rt]+=x; Rt+=lowbit (RT); }}LL getsum (int rt) {ll s=0; while (rt>0) {S+=TREE[RT]; Rt-=lowbit (RT); } return s;} int main () {while (scanf ("%d", &n), N) {memset (tree,0,sizeof (tree)); ll Ans=0; for (int i=0;i<n;i++) {scanf ("%d", &num[i]); Hash[i]=num[i]; } sort (hash,hash+n); for (int i=0;i<n;i++) {int val=bin (num[i]); ans+= (LL) I-getsum (Val); Add (val,1); } printf ("%i64d\n", ans); } return 0;}
Divide and conquer the number of reverse order can also be divided into two arrays of b,c. Number of reverse order numbers in B +c + for each c[i]b larger number
So you can use the merge sort to make the reverse order count.
5428k625ms#include<cstdio> #include <algorithm> #include <iostream> #include <cstring> using namespace std; #define LL Long Long#define lowbit (x) (x&-x) const int M=5e5+100;int num[m];int Tmp[m];int hash[m]; int n;int Bin (int val)//Two divides the discretized ordinal number {int l=0,r=n-1; while (r>=l) {int m= (L+R) >>1; if (hash[m]==val) return m+1; if (hash[m]>val) r = m-1; else l=m+1; }}ll merge_count (int l,int r) {if (l==r) {return 0; } ll cnt=0; int m= (L+R) >>1; Cnt+=merge_count (L,M); Cnt+=merge_count (M+1,R); int a=0,b=l,c=m+1; while (a<r-l+1) {if (b<=m&& (c==r+1 | | Num[b]<=num[c]) {tmp[a++]=num[b++];//Sort} else{tmp[a++]=num[c++]; Sort cnt+=m-b+1; }} for (int i=0;i<r-l+1;i++)//revert to the original sequence num[l+i]=tmp[i]; return CNT;} int main () {while (scanf ("%d", &n), N) {for (int i=0;i<n;i++) {scanf ("%d", &AMp;num[i]); Hash[i]=num[i]; } sort (hash,hash+n); for (int i=n-1;i>=0;i--) {int val=bin (num[i]); Num[i+1]=val; My discrete sequence is set to start from 1 to N, because the next part of the rule is afraid of mistakes to apply the line tree from node 1 to the beginning of the wording ... 2333} printf ("%i64d\n", Merge_count (1,n)); } return 0;}
POJ 2299 Ultra-quicksort (tree array or merge sort divide to find inverse logarithm)