Code Review
PEP 8
PEP 8 recommends snake_case for variable names, so N, Q, A, L, R, and D all violate the guidelines.
A space should be used around operators: index - 1 and R - 1
Unused variables
N and testcase are never used, so should be replaced with the throwaway _ variable.
Variable naming
N, Q, A, L, R, and D are all "almost meaningless". Yes, they are directly from the problem description, but you could do better naming them array_size, num_queries, array, left, right and difference.
Is count_length a count of lengths? Doesn't seem to be; it is more like a max_length.
Is count_temp a count of temporaries? Or is it more like a segment_length?
_, num_queries = [int(x) for x in input().split()] array = list(map(int, input().split())) for _ in range(num_queries): left, right, difference = [int(x) for x in input().split()] if left == right: print("1") continue max_length = 0 segment_length = 0 for index in range(left, right): if array[index] == array[index - 1] + difference: segment_length += 1 if index == right - 1: segment_length += 1 max_length = max(max_length, segment_length) else: segment_length += 1 # to include the first element of AP max_length = max(max_length, segment_length) segment_length = 0 print(max_length)
Optimization
Without changing the Algorithm???
Ok, you're looking for just key-hole level optimizations. Let's see what we can do.
for index in range(left, right): if array[index] == array[index - 1] + difference: ... else: ...
The above is inefficient code. Indexing into a list takes time, and you are doing it twice. Moreover, subtraction by 1 takes time, and it was to get the value which was looked up on the previous iteration!
Compare the above code with:
prev = array[left - 1] for curr in array[left:right]: if curr == prev + difference: ... else: ... prev = curr
The indexing has been replaced with iteration over an array slice, and the current value from one iteration is carried forward to as the previous value in the next iteration. That should be a win, performance wise.
segment_length = 0 for ...: if ...: ... if ...: segment_length += 1 max_length = max(max_length, segment_length) else: segment_length += 1 # to include the first element of AP max_length = ... segment_length = 0
Why are you starting the count from 0? That means you need this segment_length += 1 to account for that first element all the time. If you initialized segment_length = 1, you can skip that adjustment statement every time you reach the end of an arithmetic progression, saving another wee bit of time:
segment_length = 1 for ...: if ...: ... if ...: max_length = max(max_length, segment_length) else: max_length = ... segment_length = 1
Finally, the code I hate the most:
for index in range(left, right): if ...: ... if index == right - 1: ... else: ... ...
When does the for loop end? After index loops the final time with index = right - 1, of course. So the only time this if condition will be true is during the last iteration of the loop. During all of the remaining loop iterations, you are wasting time, subtraction 1 from right and comparing the result to index, when it can't possibly ever be true. Simply move the code to follow the loop.
_, num_queries = [int(x) for x in input().split()] array = list(map(int, input().split())) for _ in range(num_queries): left, right, difference = [int(x) for x in input().split()] if left == right: print("1") continue max_length = 0 segment_length = 1 prev = array[left - 1] for curr in array[left:right]: if curr == prev + difference: segment_length += 1 else: max_length = max(max_length, segment_length) segment_length = 1 prev = curr max_length = max(max_length, segment_length) print(max_length)
With changing the Algorithm
You explicitly requested optimization without changing the algorithm, so I'll leave you to discover where there is an algorithmic improvement to be made.
NandQequal to200000(fitting your constraints). What "time limit" is exceeded AND with that, why do you suspend the flow withinput()on each iteration? \$\endgroup\$