Recently, it seems thatAlgorithmThe problem is no longer popular. You just like the relationship between rice and rice. My second question is not double.CubeI don't know what the algorithm is. You can refer to the question "I have a second question (not double supercube )"
In fact, at first I thought it was very simple. The first solution I wrote was correct, but I hate to say that the input N can be 2,000,000,000. 2 billion ..... If n is the largest, you don't need to read it. My solution goes out for a long time. Second, it goes out of memory directly.
What should we do ??? I have been thinking about its law. In fact, I have always felt that I can't grasp it, and I still have no time to calm down, but I can't sleep until I keep this problem, so I found the time and found the rule. I set N to 16, because 16 is enough for us to see the law. If it is small, it is hard for us to establish a foothold. Print the concatenation string a with n = 16 according to my first solution:
01 0110 01101010 0110101010100010 01101010101000101010001011100010 |
This is the character printed by each loop at n = 16. We can see that the number of loops is log2 (n + 1), which is not the focus, we are looking for a rule. We can see that the N power of 2, that is, a (2 ^ N) must be 1. Why? Later.
Let's talk about the total number of partitions: According to the definition, if a number N is equal to I * I, we will regard N as the total number of partitions. I <= N
According to the question, if the index is the total number of partitions, then B [Index] = 1-A [Index]. From the perspective of the question, it is actually the inverse 0-> 1-> 0.
Next, why must a (2 ^ n) be 1? We know that each cycle, a = a + B
B is determined based on whether each of the members of a is a complete number of workers, and the length of A is also regular 2 ^ n digits. Therefore, 2 ^ N is actually a judgment on a [0 ].
It is defined according to the number of full shards. Because 0 = 0*0, it is a full shard.
B [0] = 1-A [0] = 1-0 = 1
This is why 2 ^ n must be 1.
Next, we will analyze the rules for other digits.
In fact, I was confused at the beginning, because I thought of the key point, but I could never catch it. The more I became obsessed with it, the less I had learned algorithms and did not know the data structure, I can only find my answers slowly. Now I have regretted my inactive youth.
Let's look at (2 ^ n) + 1, and you will find that it is always 0. According to the above proof, we know that (2 ^ N) + 1 is always a judgment on a [1.
1 = 1*1
So 1 is the total number of distinct, that is, a reverse operation on a [1], and 1 = 2 ^ 0 so a [1] = 1 so a [(2 ^ N) + 1] = 0
Okay. Do you see any rules here? I want to write a little bit, because I don't understand it very well, I can only write a rough
A [n] = issqrt (A [n-2 ^ (log2 (n)])? 1-A [n-2 ^ (log2 (n)]: A [n-2 ^ (log2 (n)] |
The issqrt method is used to determine whether the number is a full number of workers,CodeAs follows:
Public BoolIssqrt (DoubleN ){ReturnMath. SQRT (N). Equals (math. truncate (math. SQRT (N )));}
It can be seen that it is a judgment of the corresponding digits of olda (A before the loop). Do we also need to perform the log2 (n + 1) loop? Of course, this is not necessary. We can see that, if it is the first few digits, we only need to loop to the first few digits of log2n. It may be awkward to say, simply put,
When n = 16, we need to judge that the last time a's 0th bits (16-2 ^ (floor (log2 16) = 0
In each loop, 0 is actually a judgment of a [0], so we only need to judge the minimum xxx that contains this digit (I don't know how to say it)
We only need to get the log2 (INDEX) cycle. With so much nonsense, I have a poor expression. Let's look at the code I wrote. I wrote two types, which have the same meaning, but use recursion, it is useless.
Public IntGetvalues (IntN ){If(Getvalue (n ))Return1;ElseReturn0 ;}Public BoolGetvalue (DoubleN ){DoubleBasen = math. Floor (math. Log (n, 2 ));DoubleIndex = N-math. Pow (2, basen );If(Index = 0)Return True;BoolIssquer = issqrt (INDEX );ReturnIssquer ^ getvalue (INDEX );}
The above is a recursive method, and the following is a non-recursive method:
Public IntGetvalues (IntN ){DoubleBasen = math. Floor (math. Log (n, 2 ));BoolIssqrt =True;DoubleIndex = N-math. Pow (2, basen );While(Index> 0) {issqrt = issqrt ^ issqrt (INDEX); Index = index-math. pow (2, math. floor (math. log (index, 2 )));}ReturnIssqrt? 1: 0 ;}
The two actually mean one thing. You can understand what I mean by yourself, haha.
I know there should be better practices, such as displacement, but my capabilities are limited and I can only do it here. Finally, let's look at the performance at N = 2,000,000,000.
Amount ..... Without recursion, It is faster than one order of magnitude .....
I really don't have any scientific basis for this algorithm. I also hope that experts can give you some advice, give a formula or prove it, or give a new good algorithm.