First paste a TLE code...
# Include <iostream> # include <cstdio> # define MAXN 11111 using namespace std; int gt [MAXN <2], st [MAXN <2]; int date [MAXN]; void pushUpmax (int rt) {gt [rt] = max (gt [rt <1], gt [rt <1 | 1]);} void pushUpmin (int rt) {st [rt] = min (st [rt <1], st [rt <1 | 1]);} void build (int l, int r, int rt) {if (l = r) {gt [rt] = st [rt] = date [l]; return ;} int m = (l + r)/2; build (l, m, rt <1); build (m + 1, r, rt <1 | 1 ); pushUpmax (rt); pushUpmin (Rt);} int querygt (int v, int l, int r, int rt) // find the number of nodes smaller than v in the [l, r] range on the maximum tree. {If (l = r) return 0; if (gt [rt] <v) return r-l + 1; int m = (l + r)/2; int ret = 0; ret + = querygt (v, l, m, rt <1); ret + = querygt (v, m + 1, r, rt <1 | 1); return ret;} int queryst (int v, int l, int r, int rt) // search for [l, r] number of nodes greater than v in the interval {if (l = r) return 0; if (gt [rt]> v) return r-l + 1; int m = (l + r)/2; int ret = 0; ret + = queryst (v, l, m, rt <1); ret + = queryst (v, m + 1, r, rt <1 | 1); return ret;} int main () {int N; while (scanf ("% d", & N )! = EOF) {for (int I = 1; I <= N; I ++) {scanf ("% d", & date [I]); date [I + N] = date [I];} build (1, 2 * N, 1); int ans = 0; for (int I = 1; I <= N; I ++) for (int j = I + 1; j <= N; j ++) if (date [I]> date [j]) ans ++; for (int I = 1; I <= N; I ++) ans = min (ans, ans + queryst (date [I], I + 1, I + N-1, 1)-querygt (date [I], I + 1, I + N-1, 1); printf ("% d \ n", ans);} return 0 ;}
Although it was me, it was my attempt. Although TLE is... helpless ..
First, define the number of reverse orders:
The number of Ai> Aj in a string of numbers. Conversely, when I> j, the number of Ai <Aj.
Generally speaking, it is the number of numbers that are larger than Ai before.
Here is a brief description of my formula.
| ...... | AB | ...... |
Assuming that AB is the two adjacent numbers in the string, how does the reverse order change the positions of the two numbers?
| ...... | BA | ...... |
If (A> B) r --;
If (B> A) r ++;
Obviously, the transposition of AB is irrelevant to the following two things: | ...... |.
So what about A |... | transpose |... |?
Let's take a step-by-step look...
ABCDEFG
BACDEFG
BCADEFG
BCDAEFG
BCDEAFG
BCDEFAG
BCDEFGA
In this way, move A to the end.
How does the number of reverse Orders change in this process?
We can simply infer that the number of reverse orders added by A is greater than that of A in [B, G. The number of descending orders reduced by A is smaller than that of.
So... R + = [B, G] is greater than-[B, G] of A and smaller than.
R is the original reverse order number.
This is the origin of the above code...
Unfortunately, TLE...
The question has a special nature. Number has N for [0, N-1] each has.
So almost move Ai to the end, where there are (N-Ai-1) More than Ai, less than Ai there are Ai, so
R + = (N-Ai-1)-Ai;
This is the formula for a change.
So...
Let's do it with brute force...
#include<iostream>using namespace std;int main(){ int N; while( scanf( "%d",&N )!=EOF ) { int date[5555],ans=0; for( int i=0;i<N;i++ ) scanf( "%d",&date[i] ); for( int i=0;i<N;i++ ) for( int j=0;j<i;j++ ) if( date[j]>date[i] ) ans++; int temp=ans; for( int i=0;i<N;i++ ) { temp=temp-date[i]+(N-date[i]-1); ans=min( ans,temp ); } printf("%d\n",ans ); } return 0;}
Tree array:
#include<iostream>using namespace std;int tree[5555],N;void update( int pt,int v ){ while( pt<=N ) { tree[pt]+=v; pt+=pt&(-pt); }}int find( int pt ){ int ret=0; while( pt ) { ret+=tree[pt]; pt-=pt&(-pt); } return ret;}int main(){ int date[5555]; while( scanf("%d",&N)!=EOF ) { memset( tree,0,sizeof(tree) ); for( int i=0;i<N;i++ ) { scanf( "%d",&date[i] ); date[i]++; } int ans=0; for( int i=N-1;i>=0;i-- ) { ans+=find(date[i]); update(date[i],1); } printf( "%d\n",ans ); int temp=ans; for( int i=0;i<N;i++ ) { date[i]--; temp=temp-date[i]+(N-date[i]-1); ans=min(temp,ans); } printf( "%d\n",ans ); } return 0;}