Use this to learn the idea, then write your own version.
123 4import collections5from sortedcontainers import SortedList6 7 89class Solution(object):10 def sumCounts(self, nums):11 """12 :type nums: List[int]13 :rtype: int14 """15 MOD = 10**9+716 class BIT(object): 17 def __init__(self, n):18 self.__bit = [0]*(n+1) 19 20 def add(self, i, val):21 i += 1 22 while i < len(self.__bit):23 self.__bit[i] = (self.__bit[i]+val) % MOD24 i += (i & -i)25 26 def query(self, i):27 i += 1 28 ret = 029 while i > 0:30 ret = (ret+self.__bit[i]) % MOD31 i -= (i & -i)32 return ret33 34 def update(accu, d):35 i = sl.bisect_left(idxs[x][-1])36 accu = (accu + d*(len(nums)*(2*len(sl)-1) - (2*i+1)*idxs[x][-1] - 2*(bit.query(len(nums)-1)-bit.query(idxs[x][-1])))) % MOD37 bit.add(idxs[x][-1], d*idxs[x][-1])38 return accu39 40 idxs = collections.defaultdict(list)41 for i in reversed(xrange(len(nums))):42 idxs[nums[i]].append(i)43 result = 044 sl = SortedList(idxs[x][-1] for x in idxs)45 accu = (len(nums)*len(sl)**2) % MOD46 for i, x in enumerate(sl):47 accu = (accu-(2*i+1)*x) % MOD48 bit = BIT(len(nums))49 for x in sl:50 bit.add(x, x)51 for x in nums:52 result = (result+accu) % MOD 53 accu = update(accu, -1)54 del sl[0]55 idxs[x].pop()56 if not idxs[x]:57 continue58 sl.add(idxs[x][-1])59 accu = update(accu, +1)60 assert(accu == 0)61 return result62 63 64656667class Solution2(object):68 def sumCounts(self, nums):69 """70 :type nums: List[int]71 :rtype: int72 """73 MOD = 10**9+774 75 76 class SegmentTree(object):77 def __init__(self, N,78 build_fn=None,79 query_fn=lambda x, y: y if x is None else x if y is None else (x+y)%MOD,80 update_fn=lambda x, y: y if x is None else (x+y)%MOD):81 self.tree = [None]*(1<<((N-1).bit_length()+1))82 self.base = len(self.tree)>>183 self.lazy = [None]*self.base84 self.query_fn = query_fn85 self.update_fn = update_fn86 if build_fn is not None:87 for i in xrange(self.base, self.base+N):88 self.tree[i] = build_fn(i-self.base)89 for i in reversed(xrange(1, self.base)):90 self.tree[i] = query_fn(self.tree[i<<1], self.tree[(i<<1)+1])91 self.count = [1]*len(self.tree) 92 for i in reversed(xrange(1, self.base)): 93 self.count[i] = self.count[i<<1] + self.count[(i<<1)+1]94 95 def __apply(self, x, val):96 self.tree[x] = self.update_fn(self.tree[x], val*self.count[x]) 97 if x < self.base:98 self.lazy[x] = self.update_fn(self.lazy[x], val)99 100 def __push(self, x):101 for h in reversed(xrange(1, x.bit_length())):102 y = x>>h103 if self.lazy[y] is not None:104 self.__apply(y<<1, self.lazy[y])105 self.__apply((y<<1)+1, self.lazy[y])106 self.lazy[y] = None107 108 def update(self, L, R, h): 109 def pull(x):110 while x > 1:111 x >>= 1112 self.tree[x] = self.query_fn(self.tree[x<<1], self.tree[(x<<1)+1])113 if self.lazy[x] is not None:114 self.tree[x] = self.update_fn(self.tree[x], self.lazy[x]*self.count[x]) 115 116 L += self.base117 R += self.base118 119 120 L0, R0 = L, R121 while L <= R:122 if L & 1: 123 self.__apply(L, h)124 L += 1125 if R & 1 == 0: 126 self.__apply(R, h)127 R -= 1128 L >>= 1129 R >>= 1130 pull(L0)131 pull(R0)132 133 def query(self, L, R):134 if L > R:135 return None136 L += self.base137 R += self.base138 self.__push(L)139 self.__push(R)140 left = right = None141 while L <= R:142 if L & 1:143 left = self.query_fn(left, self.tree[L])144 L += 1145 if R & 1 == 0:146 right = self.query_fn(self.tree[R], right)147 R -= 1148 L >>= 1149 R >>= 1150 return self.query_fn(left, right)151 152 result = accu = 0153 sl = {}154 st = SegmentTree(len(nums))155 for i in xrange(len(nums)):156 j = sl[nums[i]] if nums[i] in sl else -1157 158 159 160 accu = (accu+((i-j)+2*max(st.query(j+1, i), 0)))%MOD161 result = (result+accu)%MOD162 st.update(j+1, i, 1) 163 sl[nums[i]] = i164 return result165 166 167168169170class Solution3(object):171 def sumCounts(self, nums):172 """173 :type nums: List[int]174 :rtype: int175 """176 MOD = 10**9+7177 result = 0178 for i in xrange(len(nums)):179 lookup = set()180 for j in reversed(xrange(i+1)):181 lookup.add(nums[j])182 result = (result+len(lookup)**2) % MOD183 return result184