Use this to learn the idea, then write your own version.
123 4from sortedcontainers import SortedList5 6 78def linear_sieve_of_eratosthenes(n): 9 primes = []10 spf = [-1]*(n+1) 11 for i in xrange(2, n+1):12 if spf[i] == -1:13 spf[i] = i14 primes.append(i)15 for p in primes:16 if i*p > n or p > spf[i]:17 break18 spf[i*p] = p19 return spf20 21 22MAX_N = 10**523SPF = linear_sieve_of_eratosthenes(MAX_N)24class Solution(object):25 def maximumCount(self, nums, queries):26 """27 :type nums: List[int]28 :type queries: List[List[int]]29 :rtype: List[int]30 """31 class SegmentTree(object):32 def __init__(self, N,33 build_fn=lambda x: 0,34 query_fn=lambda x, y: y if x is None else x if y is None else max(x, y),35 update_fn=lambda x, y: y if x is None else x+y):36 self.tree = [None]*(1<<((N-1).bit_length()+1))37 self.base = len(self.tree)>>138 self.lazy = [None]*self.base39 self.query_fn = query_fn40 self.update_fn = update_fn41 if build_fn is not None:42 for i in xrange(self.base, self.base+N):43 self.tree[i] = build_fn(i-self.base)44 for i in reversed(xrange(1, self.base)):45 self.tree[i] = query_fn(self.tree[i<<1], self.tree[(i<<1)+1])46 47 def __apply(self, x, val):48 self.tree[x] = self.update_fn(self.tree[x], val)49 if x < self.base:50 self.lazy[x] = self.update_fn(self.lazy[x], val)51 52 def __push(self, x):53 for h in reversed(xrange(1, x.bit_length())):54 y = x>>h55 if self.lazy[y] is not None:56 self.__apply(y<<1, self.lazy[y])57 self.__apply((y<<1)+1, self.lazy[y])58 self.lazy[y] = None59 60 def update(self, L, R, h): 61 def pull(x):62 while x > 1:63 x >>= 164 self.tree[x] = self.query_fn(self.tree[x<<1], self.tree[(x<<1)+1])65 if self.lazy[x] is not None:66 self.tree[x] = self.update_fn(self.tree[x], self.lazy[x])67 68 L += self.base69 R += self.base70 71 72 L0, R0 = L, R73 while L <= R:74 if L & 1: 75 self.__apply(L, h)76 L += 177 if R & 1 == 0: 78 self.__apply(R, h)79 R -= 180 L >>= 181 R >>= 182 pull(L0)83 pull(R0)84 85 def query(self, L, R):86 if L > R:87 return None88 L += self.base89 R += self.base90 self.__push(L)91 self.__push(R)92 left = right = None93 while L <= R:94 if L & 1:95 left = self.query_fn(left, self.tree[L])96 L += 197 if R & 1 == 0:98 right = self.query_fn(self.tree[R], right)99 R -= 1100 L >>= 1101 R >>= 1102 return self.query_fn(left, right)103 104 def add(i, d):105 x = nums[i]106 if SPF[x] != x:107 return108 if d == 1:109 lookup[x].add(i)110 if len(lookup[x]) == 1:111 st.update(0, len(nums)-2, d)112 elif i == lookup[x][0]:113 st.update(i, lookup[x][1]-1, d)114 elif i == lookup[x][-1]:115 st.update(lookup[x][-2], i-1, d)116 if d == -1:117 lookup[x].remove(i)118 119 lookup = collections.defaultdict(SortedList)120 st = SegmentTree(len(nums)-1)121 for i in xrange(len(nums)):122 add(i, +1)123 result = [0]*len(queries)124 for i, (idx, x) in enumerate(queries):125 if nums[idx] != x:126 add(idx, -1)127 nums[idx] = x128 add(idx, +1)129 result[i] = st.tree[1] 130 return result131