Question link:
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1394
Question:
For the number of N numbers composed of the N numbers 0-n-1, define a number in reverse order (the number above is greater than the number below ). Move the first number to the last position to obtain a new sequence and a new number of reverse orders. You can move n-1 times in total to obtain n reverse orders and ask what the minimum number of these N reverse orders is.
Solution:
1. first obtain the number of reverse orders of the first sequence.
Based on the characteristics of the question, a 0-(n-1) Line Segment tree is created, and each interval stores the number of numbers in the current interval.
For each number, find the number of existing numbers in n-1 (because all the numbers before the number are pushed to the line segment tree), and then press the number in.
Add up the reverse order before each number to construct the entire reverse order number.
2. When the first one is moved to the end, there will be 0 after it -- (save [1]-1) the total number of save [1] is smaller than that of save [I, total n-1-save [1] is larger than save [1]
So get the recursive formula, sum = sum-save [I] + (n-1-save [I]).
Code:
# Include <iostream> # include <cmath> # include <cstdio> # include <cstdlib> # include <string> # include <cstring> # include <algorithm> # include <vector> # include <map> # include <stack> # include <queue> # define EPS 1e-6 # define Inf (1 <20) # define PI ACOs (-1.0) using namespace STD; # define lson L, M, RT <1 # define rson m + 1, R, (RT <1) | 1 # define maxn 5100int sum [4 * maxn], save [maxn]; void build (int l, int R, int RT) {sum [RT] = 0; // indicates that this interval has more than one If (L = r) return; int M = (L + r)> 1; build (lson); Build (rson); return ;} int query (int l, int R, int L, int R, int RT) {If (L <= L & R> = r) // if you want to find a range greater than the current range, return the current range return sum [RT]; int M = (L + r)> 1, temp = 0; if (r <= m) return query (L, R, lson); else if (L> m) return query (L, R, rson ); else {temp + = query (L, R, lson); temp + = query (L, R, rson); Return temp ;}} void pushup (int rt) // update upwards. Update upwards upon each insert. Note that {sum [RT] = sum [RT <1] + sum is overwritten. [RT <1 | 1];} void Update (INT target, int L, int R, int RT) {If (L = r) {sum [RT] ++; return;} int M = (L + r)> 1; if (target <= m) Update (target, lson ); else Update (target, rson); pushup (RT); return;} int main () {int N, temp; while (scanf ("% d", & N )! = EOF) {int sum = 0; build (0, n-1, 1); // note that the interval is 0-(n-1) for (INT I = 1; I <= N; I ++) {scanf ("% d", & save [I]); sum + = query (save [I], n-1, 0, n-1, 1 ); update (save [I], 0, n-1, 1);} int ans = sum; For (INT I = 1; I <n; I ++) {sum + = n-2 * save [I]-1; ans = min (sum, ANS);} printf ("% d \ n", ANS);} return 0 ;}