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
<<">