hdu 5147 Sequence II [Fenwick tree / tree line]

Sequence II
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

 

Problem Description
Long long ago, there is a sequence A with length n. All numbers in this sequence is no smaller than 1 and no bigger than n, and all numbers are different in this sequence.
Please calculate how many quad (a,b,c,d) satisfy:

1≤a<b<c<d≤n
Aa<Ab
Ac<Ad
Input
The first line contains a single integer T, indicating the number of test cases.
Each test case begins with a line contains an integer n.
The next line follows n integers A1,A2,…,An.

[Technical Specification]
1 <= T <= 100
1 <= n <= 50000
1 <= Ai <= n

Output
For each case output one line contains a integer,the number of quad.

Sample Input
1
5
1 3 2 4 5

Sample Output
4

The meaning of problems: there are a number of length n columns A, count each column are between 1 to n, and the number of columns in the two numbers are not identical exist.
Please count how many quads (a, b, c, d ) are met:

1≤a<b<c<d≤n
Aa<Ab
Ac<Ad


Thinking:
This is the road Fenwick tree / tree line basis problem. We usually updates are input order from 1 to n update segment tree or tree-like array, there are some questions you need to range achievements to his values given size, the number entered into the corresponding position (typically corresponding to the marker position), and related operations, even so this question.
We talk about the practice of Fenwick tree, tree line the same way, just write a little trouble. This question stands to reason that we need a time to determine the number of four, but will obviously t, so as much as we enumerate a number (This question is to determine b or c can be determined, we are here to talk about the determined b practice). Since determine b, we have to think of ways to determine the front b smaller than its number back and it satisfies Ac <Ad number, so here we introduce a prefix and suffix and to maintain. For the beginning, all from 1 to n point Fenwick tree is not marked, whenever you enter a number, such as input 5, we will put it in that position 5 on (ie to update the tree like array to mark the position of 5 to 1), so we went to inquire how much the number is 5 in front of a marked, indicating that these numbers are the first to be entered, the position in front of the number, this way we maintain the one Ab b is smaller than the foregoing number of array number .
Then how do we determine that those b behind it? Here we can count a bit, for the i-th a [i] input, we have calculated the foregoing it is smaller than the number of pre [i], i + 1 then to the number of positions, the number of which is larger than is na [i] - (i- 1-pre [i]), na [i] , i represents the number of how much this latter position, i-1-pre [i ] i in front of representative of how many the number ratio of a [ i] large, so that the back can calculate the number i is greater than the number of A [i] . This suffix and maintenance out of position b enumerate the number of possible species for each point can add up, pay attention to the answer may burst int.

Code:

 1 #include "stdio.h"
 2 #include "string.h"
 3 const int N=1e5+5;
 4 
 5 int t,n,a[N],c[N];
 6 long long ans,pre[N],last[N];
 7 
 8 int lowbit(int x)
 9 {
10     return x&(-x);
11 }
12 
13 int update(int x)
14 {
15     for(intX = I; I <= n-; I + = lowbit (I))
 16          C [I] ++;                       /// mark this point 
. 17  }
 18 is  
. 19  int GetSum ( int X)
 20 is  {
 21 is      int SUM = 0 ;
 22 is      for ( int i = X; i> = . 1 ; I- = lowbit (i))
 23 is          SUM + = C [i];                   /// operator prior to a number larger than the number i of the smaller [i] 
24      return SUM;
 25  }
 26 is  
27  int main ()
 28  {
 29      Scanf ("%d",&t);
30     while(t--)
31     {
32         ans=0;
33         memset(c,0,sizeof(c));
34         memset(pre,0,sizeof(pre));
35         memset(last,0,sizeof(last));
36         scanf("%d",&n);
37         for(int i=1;i<=n;i++)
38         {
 39              Scanf ( " % D " , & A [I]);
 40              pre [I] GetSum = (a [i]);            /// pre [I] Representative than a [i] is the number of small number of 
41 is              Update ; (A [I])
 42 is          }
 43 is          for ( int I = n-; I> = . 1 ; i-- )
 44 is              Last [I] = Na [I] - (I- . 1 -pre [I]);      // / calculated i rear position than a [i] a large number of values 
45          for ( int i = n-; i> = . 1 ; i-- )
 46 is              Last [i] + = Last [i + . 1];              /// accumulated even i later point satisfies Ac <the number Ad of
 47          for (int i =. 1; i <= n-; i ++)
 48              ANS + = (pre [i] * Last [i +. 1]);        / // enumeration b answer accumulated position 
49          the printf ( " % LLD \ n- " , ANS);
 50      }
 51 is      return  0 ;
 52 is }

 

Guess you like

Origin www.cnblogs.com/Satan666/p/11279976.html