Question link: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1394
Solution Report: Give a sequence, find the reverse Number of the sequence, and then move the first number to the last one in sequence. What is the reverse Number of the sequence with the smallest backward number in this process?
One advantage of this problem is that the input sequence must be 0 to n-1, so discretization is not allowed, another benefit is that we can calculate the total number of numbers larger and smaller than each in this sequence at the O (1) time. At first I didn't realize that, it's silly to use a two-layer for loop to calculate every time. Of course it's so decisive. When a number is moved from the first to the last, the change in the reverse order is equal to the original reverse order number plus the number of all numbers greater than this number in this sequence, and then the number of all ratios. A small number.
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 const int maxn = 5000+5; 7 int que[maxn]; 8 struct node 9 {10 int data,l,r;11 }tree[2*maxn];12 void maketree(int p)13 {14 if(tree[p].l == tree[p].r)15 return ;16 int mid = (tree[p].l + tree[p].r) / 2;17 tree[2*p].data = 0;18 tree[2*p].l = tree[p].l;19 tree[2*p].r = mid;20 maketree(2*p);21 tree[2*p+1].data = 0;22 tree[2*p+1].l = mid + 1;23 tree[2*p+1].r = tree[p].r;24 maketree(2*p+1);25 }26 int find(int p,int l,int r)27 {28 if(l > r)29 return 0;30 if(tree[p].l == l && tree[p].r == r)31 return tree[p].data;32 int mid = (tree[p].l + tree[p].r) / 2;33 if(r <= mid)34 return find(2*p,l,r);35 if(l <= mid && r > mid)36 return find(2*p,l,mid) + find(2*p+1,mid +1,r);37 else return find(2*p+1,l,r);38 }39 void push(int p,int d)40 {41 tree[p].data++;42 if(tree[p].l == tree[p].r)43 return ;44 int mid = (tree[p].l + tree[p].r) / 2;45 if(d <= mid)46 push(2*p,d);47 else push(2*p+1,d);48 }49 int main()50 {51 int n;52 while(scanf("%d",&n)!=EOF)53 {54 for(int i = 0;i < n;++i)55 scanf("%d",&que[i]);56 tree[1].data = 0;57 tree[1].l = 0;58 tree[1].r = n-1;59 maketree(1);60 int tot = 0;61 for(int i = 0;i < n;++i)62 {63 tot += find(1,que[i] + 1,n-1);64 push(1,que[i]);65 }66 int ans = tot;67 for(int i = 0;i < n;++i)68 {69 tot = tot - que[i] + n - que[i] - 1;70 ans = min(tot,ans);71 }72 printf("%d\n",ans);73 }74 return 0;75 }
View code