Как дерево Фенвика было использовано для решения нижеприведенной проблемы
given N points in a plane (numbered 1 through N); for each valid i, the i-th point is Pi=(i,Ai). There are N−1 line segments between them (numbered 1 through N−1); for each valid i, the i-th line segment is formed by connecting the points Pi and Pi+1 . You should answer Q queries. In each query, a laser beam is fired horizontally to the right, from a point (x1,y) to a point (x2,y) (where it stops and does not propagate further). Find the number of line segments it collides with on the way. The beam is considered to collide with a line segment if it intersects or touches this segment, except when the left endpoint of this segment is (x2,y) or its right endpoint is (x1,y).
Я хочу знать, как эта логика была реализована в программе follwing.Пожалуйста, подробно объясните, как работает progrmm
Input The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows. The first line of each test case contains two space-separated integers N and Q . The second line contains N space-separated integers A1,A2,…,AN . Each of the next Q lines contains three space-separated integers x1, x2 and y describing a query.
Output For each query, print a single line containing one integer ― the number of line segments the beam collides with.
1 4 3 1 3 5 1 2 4 4 1 2 3 1 4 1
Что я уже пробовал:
def isolateOneBit(n): return n & -n def getSum(BIT, ind): s = 0 num = ind while num > 0: s += BIT[num] # print(bin(num)) num -= isolateOneBit(num) return s def rangeSum(BIT,l,u): uSum = getSum(BIT, u) lSum = getSum(BIT,l-1) return uSum-lSum def updateSums(BIT, nBIT, ind, delta): while(ind<=nBIT): # print(bin(ind)) BIT[ind] += delta ind += isolateOneBit(ind) #Fenwick tree end def main(): t = int(input()) while t: t-=1 n, q = map(int, input().split()) pts = list(map(int, input().split())) qArr = [] for i in range(q): quer = list(map(int, input().split())) quer.append(i) qArr.append(quer[:]) ptsArr = [] for i in range(1,n): a = pts[i-1] b = pts[i] if a>b: a,b = b,a ptsArr.append((a, b, i)) # print(ptsArr) startArr = sorted(ptsArr[:]) # print("startArr",end=' ') # print(startArr) endArr = sorted(ptsArr[:],key = lambda x: x[1]) # print("endArr",end=' ') # print(endArr) qArr.sort(key=lambda x: x[2]) # print("qArr",end=' ') # print(qArr) # Basic setup done fenStart = [0 for i in range(n+10)] fenEnd = [0 for i in range(n+10)] answers = [] i = 0 j = 0 for query in qArr: while(i<n-1 and startArr[i][0]<=query[2]): updateSums(fenStart,n+1,startArr[i][2],1) i += 1 while(j<n-1 and endArr[j][1]<query[2]): updateSums(fenEnd,n+1,endArr[j][2],1) j += 1 # print(i,j,query,endArr[j][1]) st = rangeSum(fenStart,query[0],query[1]-1) ed = rangeSum(fenEnd,query[0],query[1]-1) answers.append((query[3],ed-st)) answers.sort() for i in answers: print(-i[1]) if __name__ == "__main__": main()