A strange question
I have not understood the discussion on searching from the left or from both sides in the purple book. How can I find the only element ?)
The method is the method described in the book, similar to the method described in the following figure. However, this question requires preprocessing to store the nearest same number of locations on both sides.
For (INT I = 1; I <= N; I ++) {Prev [I] = R [A [I]; next [Prev [I] = I; R [A [I] = I;} // records the position where element a [I] appeared last time, because it is traversed from left to right, therefore, the last occurrence is exactly what Prev [I] requires: // Prev [I]. The position of the nearest element on the left is the same as that of the element on the I position. // next [I]View code
Then, recursively check whether it meets the meaning of the question...
Search from the left
Int DFS (int l, int R) {If (L> = r) return 1; int P; For (P = L; P <= r; P ++) if (next [p]> r & Prev [p] <L) break; If (P> r) return 0; return DFS (L P-1) & DFS (p + 1, R) ;}// the DFS of TLE, from left to rightView code
Tle, and then start searching from both sides.
int dfs(int l, int r) { if(l >= r) return 1; for(int i = 0; i <= (r-l+1)/2; i++) { if(next[l+i] > r && prev[l+i] < l) return dfs(l, l+i-1) && dfs(l+i+1, r); if(next[r-i] > r && prev[r-i] < l) return dfs(l, r-i-1) && dfs(r-i+1, r); } return 0;} View code
But it's still TLE, so now I have a headache. I can't figure out what else can be optimized for a long time.
The results were compared by referring to the online experts. We found that the map was used for storage, avoiding the use of memset, but changed to map. clear () (map. clear is very fast? =)
The following is just to change map to an array, and then use only one memset statement to see the time increase.
AC code
# Include <iostream> # include <cstdio> # include <cstring> # include <algorithm> # include <map> # define maxn 200000 + 5 using namespace STD; int Prev [maxn], next [maxn]; int A [maxn]; Map <int, int> r; int N;/* int DFS (int l, int R) {If (L> = r) return 1; int P; For (P = L; P <= r; P ++) if (next [p]> r & Prev [p] <L) break; If (P> r) return 0; return DFS (L P-1) & DFS (p + 1, R) ;}* // the DFS of TLE, int DFS from left to right (int l, int R) {If (L> = r) Return 1; for (INT I = 0; I <= (R-l + 1)/2; I ++) {If (next [L + I]> r & Prev [L + I] <L) return DFS (L, L + i-1) & DFS (L + I + 1, R); If (next [r-I]> r & Prev [r-I] <L) return DFS (L, r-i-1) & DFS (r-I + 1, R);} return 0;} // the idea of finding int main () {int testcase from both sides; scanf ("% d", & testcase); While (testcase --) {// memset (prev, 0, sizeof (prev); // memset (next, 0, sizeof (next); // memset (A, 0, sizeof (a); // memset (R, 0, sizeof (R )); R. clear (); scanf ("% d", & N); For (INT I = 1; I <= N; I ++) {scanf ("% d ", & A [I]); Prev [I] = 0; next [I] = n + 1;} For (INT I = 1; I <= N; I ++) {Prev [I] = R [A [I]; next [Prev [I] = I; R [A [I] = I ;} // record the position where element a [I] appeared last time. Because it is traversed from left to right, the last position displayed last time is exactly what Prev [I] requires. // Prev [I], the position of the nearest element on the left that is the same as the element on the I position. // next [I] Similarly, puts (DFS (1, N )? "Non-boring": "boring ");}}View code
The time complexity is O (nlogn)
In the future, we will try not to use the memset statement for arrays with large data volumes, although linear ......
PS. For the code of this question, refer to the code of a great God on the Internet. The code I wrote at the beginning was ugly, especially during the pre-processing Section. No one knows = after it is posted.
UV 1608, non-boring Sequences