Dynamic Programming solves the problem of the number of substrings that do not contain the same number

Source: Internet
Author: User

Dynamic Programming solves the problem of the number of substrings that do not contain the same number

Competition description

The fairy spirit witch Lulu is more enthusiastic about magic than ordinary people. If she finds any old magic, she always tries her best to obtain it and then studies and analyzes it. Recently, he got a strange magic scroll from vija, the evil little mage;

The Magic Scroll contains a large number, and according to the description on the scroll, the magic power index comes from the number of "Magic ranges" in the number;

The so-called "Magic interval" refers to a continuous closed interval, and all numbers in this interval are different;

Now, Lulu wants to know the magic power index. Can you help her?



Input

Enter a positive integer T, indicating the number of samples, 1 ≤ T ≤ 10.

For each example, enter a positive integer n, indicating the number of numbers on the scroll (1 ≤ n ≤ 106 );

Input n integers, indicating the number of I on the scroll (0 ≤ ai ≤ 106 ).

Output

For each example, a positive integer (power index) is output.

The question guarantee is within the int range.

Sample Input

1
3
1 2 3

Sample output

6

Prompt

  1. Use scanf () to read data ();

  2. For example, there are 6 magic ranges: {1}, {2}, {3}, {1, 2}, {2, 3}, {2, 3, so the power is 6.


    Idea: The data range of this question is 1000000. Theoretically, the maximum time complexity is less than nlog (n). First, we should consider using dynamic programming to solve the problem. The goal of dynamic planning is to find the state transition equation. Assume that a total of n numbers are in the array num [n], and the solution containing the first I number is answer [I]. then we need to find the state transition equation T so that answer [I + 1] = T (answer [I]) (1) so what is the relationship between answer [I + 1] and answer [I + 1?
    Obviously, the "magic space" created by the first I + 1 digit must contain the "magic space" created by the first I number, in addition, there is a part of the magic space containing the number I. That is to say, the (1) formula can be further written as: answer [I + 1] = answer [I] + F (I + 1) (2) Where F (I + 1) the number of magic spaces that contain the I + 1 number. So the objective of this question is further transformed into: when we have I + 1 number, how much magic space does it have that number I + 1?
    Of course, we can start back from the number of I + 1 and add the numbers to the empty set one by one until the set cannot retain no repeated numbers, the length of this set is the number of sequences containing numbers I + 1 (All sequences are subsequences with suffixes in turn ). Take the sequence 1 2 3 1 with a length of 4 as an example. When it contains three numbers, the magic space is 6. That is, 1, 2, 3, 123. When the fourth number is added, the numbers 231,31, 1 (different from the first 1) are added, so the magic space of 1 2 3 1 is 9. To optimize the F process, we can try to adopt some clever practices. It is unwise to constantly add numbers and check whether the sequence is legal.When we look back from the number I, it is obvious that when we reach the position j, and num [j] = num [I], it must be stopped because the set has already been repeated. Then, when we trace back from I + 1, it is impossible to exceed the position of j.(Because it still contains the number num [I], which is the same as num [j ). We set the position of the first same number of I TO mark [I]. therefore, for each backtracking, we can set a limit value (initially 0) to indicate the most forward position we can achieve. In the process of backtracking Because we cannot exceed mark [k. Backtracing ends with the following conditions: the limit or num [k] = num [I + 1]. The backtracing distance is F (I + 1 ). Then we get the complete state transition equation.
    The Code completed by the above ideas is as follows:
    # Include
        
         
    # Define deusing namespace std; int f (int n) {return (n + 1) * n/2;} int num [1000000]; int mark [1000000]; int main () {int I, j, n, T; scanf ("% d", & T); // cin> T; while (T --) {cin> n; memset (mark, 0, sizeof (mark); for (I = 0; I
         
          
    > Num [I];} int sum = 0; for (I = 0; I
          
           
    = Limit; j --) {if (num [j] = num [I]) break; temp ++; if (mark [j]> limit) limit = mark [j];} mark [I] = j + 1; // cout <
           <<" "<<
            

    Unfortunately, the time limit exceed occurred on the acm system ). Looking back at our practices and our original intention, we will find that if we are faced with n completely different numbers, the distance between each backtracking at the position I will be I, the time complexity of the algorithm is terrible.
    Let's see where we are stupid?
    The silly part is the bold text in the previous section: When we look back from the number I, it is obvious that when we reach the position j, and num [j] = num [I], it must be stopped because the set has already been repeated. Then, when we trace back from I + 1, it is impossible to exceed the position of j.

    This practice is not smart. In fact, we should not save the position of the first digit of each number. Although this can help us reduce the Backtracking distance, think carefully,Is the distance that can be traced back at the I + 1 position not only related to the distance that can be traced back at the I + 1 position?

    Let's sort out our ideas. If we have an I number and have obtained a solution (the foothold of Dynamic Planning), when we add the I + 1 number, the obtained result can be obtained by finding F (I + 1) (the number of intervals containing the I + 1 number, the number of intervals is actually the length of the longest magic space containing the number I + 1. The length is actually the length of the longest magic space containing the number I, plus 1!
    Yes, for F, it is still a dynamic planning problem, but it is a very simple dynamic planning problem:

    F (I + 1) = F (I) + 1 (3)

    But we still need to get mark [num [I + 1], because the former number J, which is the same as the number I + 1, may contain F (I) in the magic range, J will "truncate" F (I) Because I + 1 number is added ).

    Therefore, we do not have to backtrack this problem (that is, the current time complexity is On). We only need to analyze the two situations when examining the I + 1 Number:

    The maximum space that contains the number I does not contain the same number as I + 1: F (I + 1) = F (I) + 1

    Otherwise, F (I + 1) = I + 1-j.


    Note that the variable name in this article does not exactly correspond to the program. The implementation methods of the program may be more abstract, but the idea is described above.

    Code

    #include
             
              #includeusing namespace std;int num[1000001];int limit[1000001];int max_[1000001];int main(){    int i,j,n,T;    scanf("%d",&T);//    scanf_(T);    while(T--)    {        scanf("%d",&n);    //    scanf_(n);        memset(max_,-1,sizeof(max_));        for(i=0;i
              
               







    <<">

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.