Hdu 5147 Sequence II (tree number or line segment tree + input plug-in prefix and + suffix and)
Question:
Given 1 ~ An array of n is saved in the array A [] and the number of subscripts (a, B, c, d) meet the following requirements:
A
Resolution:
The range of n in the question is 50000, and the complexity of O (n ^ 2) definitely times out. This question is clearly about the log2 (n) algorithm. For this question, you can use a line segment tree or a tree array, and also use an input plug-in. Otherwise, it will time out.
Ideas (refer to others' practices)
The position of the enumerated c, the number of methods in each enumeration is 1 ~ Multiply the number of (a, B) in C-1 by c ~ The number of (c, d) in n. The answer is accumulated.
1 ~ The number of (a, B) in C-1 is equal to the position of enumeration B. Then, it is calculated that the number of (A, B) before B is smaller than that of a [B]. The value must be saved, in the next enumeration of c, the value plus the number of smaller numbers in front of C-1 than a [C-1] is 1 ~ The number of (a, B) in C-1, that is, when B is equal to C-1, it has been calculated because it is before B is enumerated.
When we calculate c, we only calculate the number of methods smaller than c. This only satisfies the number of binary groups smaller than c. The binary groups before c must be included, so the number before c is smaller than that before c.
Use a tree array. The n value range of this question is 50000, and it is critical that each number is different. So we opened up n positions. At the beginning, each position is 0. In fact, each position is either 0 or 1, because each number has only one.
For example, 1 3 2 4 5
At the beginning, the c array 0 0 0 0 0
Make statistics first, and then input it, because the number before calculation a [I] is smaller than it, not its own, and the tree array should include its own in calculation and.
I = 1, the sum prefix of the tree array and pre [1] = 0,
0 0 0 0 0, input 1, change to 1 0 0 0 0
I = 2, a [2] = 3. It depends on the number of numbers in front of 3, that is, the number of in front of the three positions in the c array indicates that the input has been made,
It is found that 1 0 0 0 the first three numbers have only one 1, that is, pre [2] = 1 (there is only one smaller number before the second number of input). After Entering 3, the c array is changed to 1 0 1 0 0
I = 3, a [3] = 2, depending on the number of front 2, that is, to see the number of front 1 in front of the first two positions of the c array, it is found that there is only one of the first two numbers of 10100, that is, pre [3] = 1.
If the prefix and can be calculated, then the suffix and = num2 [I] = n-I-a [I] + num [I] + 1;
AC code
# Include
# Include
# Include
# Include
Using namespace std; typedef long ll; const int INF = 0x3f3f3f3f; const int N = 5e4 + 10; int n; ll C [N], a [N]; inline void read (ll & x) {int flag = 0; x = 0; char c = getchar (); if (c = '-') flag = 1; while (c <'0' | c> '9') {if (c = '-') flag = 1; c = getchar ();} while (c> = '0' & c <= '9') x = x * 10 + c-'0', c = getchar (); if (flag) x =-x;} inline int lowbit (int x) {return x & (-x);} int query (int x) {int ret = 0; while (x> 0) {ret + = C [x]; x-= lowbit (x);} return ret;} void add (int x, int d) {while (x <= n) {C [x] + = d; x + = lowbit (x) ;}} int num [N], num2 [N]; int main () {int T; scanf ("% d", & T); while (T --) {ll ans = 0, pre = 0; scanf ("% d", & n); memset (C, 0, sizeof (C); for (int I = 1; I <= n; I ++) {read (a [I]); num [I] = query (a [I]); // calculate the number num2 [I] = n-I-a [I] + num [I] + 1 that is smaller than a [I] before a [I; // calculate the number add (a [I], 1) greater than a [I] after a [I]; ans + = pre * num2 [I]; pre + = num [I];} printf ("% lld \ n", ans);} return 0 ;}