Problem:
 Score : 600 points    Problem Statement We have N colored balls arranged in a row from left to right; the color of the i -th ball from the left is c_i .  You are given Q queries. The i -th query is as follows: how many different colors do the l_i -th through r_i -th balls from the left have?      Constraints  1\leq N,Q \leq 5 \times 10^5  1\leq c_i \leq N  1\leq l_i \leq r_i \leq N  All values in input are integers.         Input Input is given from Standard Input in the following format:  N  Q  c_1  c_2  \cdots  c_N  l_1  r_1  l_2  r_2  :  l_Q  r_Q       Output Print Q lines. The i -th line should contain the response to the i -th query.        Sample Input 1 4 3
1 2 1 3
1 3
2 4
3 3      Sample Output 1 2
3
1   The 1 -st, 2 -nd, and 3 -rd balls from the left have the colors 1 , 2 , and 1 - two different colors.  The 2 -st, 3 -rd, and 4 -th balls from the left have the colors 2 , 1 , and 3 - three different colors.  The 3 -rd ball from the left has the color 1 - just one color.        Sample Input 2 10 10
2 5 6 5 2 1 7 9 7 2
5 5
2 4
6 7
2 2
7 8
7 9
1 8
6 9
8 10
6 8      Sample Output 2 1
2
2
1
2
2
6
3
3
3

Solution (Python):
def getN():
    return int(input())
def getNM():
    return map(int, input().split())
def getList():
    return list(map(int, input().split()))
def getArray(intn):
    return [int(input()) for i in range(intn)]
def input():
    return sys.stdin.readline().rstrip()
def rand_N(ran1, ran2):
    return random.randint(ran1, ran2)
def rand_List(ran1, ran2, rantime):
    return [random.randint(ran1, ran2) for i in range(rantime)]
def rand_ints_nodup(ran1, ran2, rantime):
  ns = []
  while len(ns) < rantime:
    n = random.randint(ran1, ran2)
    if not n in ns:
      ns.append(n)
  return sorted(ns)

def rand_query(ran1, ran2, rantime):
  r_query = []
  while len(r_query) < rantime:
    n_q = rand_ints_nodup(ran1, ran2, 2)
    if not n_q in r_query:
      r_query.append(n_q)
  return sorted(r_query)

from collections import defaultdict, deque, Counter
from sys import exit
from decimal import *
import heapq
from math import sqrt
from fractions import gcd
import random
import string
import copy
from itertools import combinations, permutations, product
from operator import mul, itemgetter
from functools import reduce
from bisect import bisect_left, bisect_right

import sys
sys.setrecursionlimit(1000000000)
mod = 10 ** 9 + 7





class BIT:
    def __init__(self, N):
        self.N = N
        self.bit = [0] * (N + 1)
        self.b = 1 << N.bit_length() - 1

    
    def add(self, a, w):
        x = a
        while(x <= self.N):
            self.bit[x] += w
            x += x & -x

    def get(self, a):
        ret, x = 0, a - 1
        while(x > 0):
            ret += self.bit[x]
            x -= x & -x
        return ret

    
    def cum(self, l, r):
        return self.get(r) - self.get(l)

    def lowerbound(self,w):
        if w <= 0:
            return 0
        x = 0
        k = self.b
        while k > 0:
            if x + k <= self.N and self.bit[x + k] < w:
                w -= self.bit[x + k]
                x += k
            k //= 2
        return x + 1



N, Q = getNM()
C = getList()
que = [getList() for i in range(Q)]


que_d = defaultdict(list)
for i in range(Q):
    que_d[que[i][1]].append([que[i][0], i])
ans = [0] * Q

dic = defaultdict(lambda: -float('inf'))
bit = BIT(N)

for i in range(N):
    
    if dic[C[i]] >= 1:
        bit.add(dic[C[i]], -1)
    
    
    dic[C[i]] = i + 1
    bit.add(dic[C[i]], 1)

    
    if len(que_d[i + 1]) > 0:
        for l, j in que_d[i + 1]:
            
            ans[j] = bit.cum(l, i + 2)

for i in ans:
    print(i)

Solution (Python):
import numpy as np
def proc(C, L, R, Order, N, Q):
    pl = pr = 0
    ans = 0
    A = np.zeros(N+1, dtype=np.int32)
    Ans = np.zeros(Q, dtype=np.int32)
    for idx_LR in Order:
        l = L[idx_LR]
        r = R[idx_LR]
        while pr < r:
            pr += 1
            c = C[pr]
            if A[c] == 0:
                ans += 1
            A[c] += 1
        while pl > l:
            pl -= 1
            c = C[pl]
            if A[c] == 0:
                ans += 1
            A[c] += 1
        while pr > r:
            c = C[pr]
            A[c] -= 1
            if A[c] == 0:
                ans -= 1
            pr -= 1
        while pl < l:
            c = C[pl]
            A[c] -= 1
            if A[c] == 0:
                ans -= 1
            pl += 1
        Ans[idx_LR] = ans
    return Ans


numba_config = [
    ["proc", "i4[:](i4[:],u4[:],u4[:],i8[:],i4,i4)"]
]
import os
import sys
if sys.argv[-1] == "ONLINE_JUDGE":
    from numba.pycc import CC
    cc = CC("my_module")
    for func_name, types in numba_config:
        cc.export(func_name, types)(vars()[func_name])
        cc.compile()
    exit()
elif os.name == "posix":
    exec(f"from my_module import {','.join(func_name for func_name, _ in numba_config)}")
else:
    from numba import njit
    for func_name, types in numba_config:
        vars()[func_name] = njit(types, cache=True)(vars()[func_name])
    print("compiled", file=sys.stderr)


def main():
    input = sys.stdin.buffer.readline
    N, Q = map(int, input().split())
    C = np.empty(N+1, dtype=np.int32)
    C[0] = 0
    C[1:] = np.array(input().split(), dtype=np.int32)
    LR = np.array(sys.stdin.buffer.read().split(), dtype=np.uint32)
    L = LR[::2]
    R = LR[1::2]
    B = L>>9<<20|R
    Idx = (L>>9&1).astype(np.bool)
    B[Idx] = L[Idx]>>9<<20|(1<<20)-R[Idx]
    Order = np.argsort(B)
    Ans = proc(C, L, R, Order, N, Q)
    print("\n".join(map(str, Ans.tolist())))

main()

Solution (Python):
class BIT:
    """
    https://tjkendev.github.io/procon-library/python/range_query/bit.html
    """
    def __init__(self, n):
        self.n = n
        self.data = [0] * (n + 1)
        self.el = [0] * (n + 1)

    def sum(self, i):
        s = 0
        while i > 0:
            s += self.data[i]
            i -= i & -i
        return s

    def add(self, i, x):
        assert i > 0
        self.el[i] += x
        while i <= self.n:
            self.data[i] += x
            i += i & -i

    def get(self, i, j=None):
        if j is None:
            return self.el[i]
        return self.sum(j) - self.sum(i)


def solve(n, q, c_list, lr_list):
    lri_list = [[lr_list[i][0], lr_list[i][1], i] for i in range(q)]
    
    lri_list_s = sorted(lri_list, key=lambda x: x[1])
    
    color_index = [0] * (n + 1)
    
    bit = BIT(n)

    res = [0] * q

    r_temp = 0
    for l, r, i in lri_list_s:
        while r > r_temp:
            r_temp += 1
            c = c_list[r_temp - 1]
            c_ind = color_index[c]
            if c_ind > 0:
                bit.add(c_ind, -1)
            color_index[c] = r_temp
            bit.add(r_temp, 1)
        
        res[i] = bit.get(l - 1, r)
    
    return res


def main():
    n, q = map(int, input().split())
    c_list = list(map(int, input().split()))
    lr_list = [list(map(int, input().split())) for _ in range(q)]
    res = solve(n, q, c_list, lr_list)
    for r in res:
        print(r)


def test():
    assert solve(4, 3, [1, 2, 1, 3], [[1, 3], [2, 4], [3, 3]]) == [2, 3, 1]
    assert solve(10, 10, [2, 5, 6, 5, 2, 1, 7, 9, 7, 2], [
        [5, 5], [2, 4], [6, 7], [2, 2], [7, 8], [7, 9], [1, 8], [6, 9], [8, 10], [6, 8]
    ]) == [1, 2, 2, 1, 2, 2, 6, 3, 3, 3]


if __name__ == "__main__":
    test()
    main()

Solution (Python):
import sys

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline


class BIT:
    def __init__(self, n):
        self.n = n
        self.data = [0] * (n + 1)

    def add(self, i, x=1):
        i += 1
        while i <= self.n:
            self.data[i] += x
            i += i & -i

    def get_sum(self, i):
        i += 1
        x = 0
        while i > 0:
            x += self.data[i]
            i -= i & -i
        return x

    
    def get_sum_range(self, l, r):
        return self.get_sum(r - 1) - self.get_sum(l - 1)


def main():
    N, Q = map(int, readline().split())
    C = list(map(int, readline().split()))
    LR = map(int, read().split())

    prev = [-1] * (N + 1)
    ps = [[] for _ in range(N)]
    for i, c in enumerate(C):
        if prev[c] != -1:
            ps[prev[c]].append(i)
        prev[c] = i

    qs = [[] for _ in range(N)]
    for i, (l, r) in enumerate(zip(*[iter(LR)] * 2)):
        qs[l - 1].append((r - 1, i))

    ans = [0] * Q
    bit = BIT(N)

    for l in range(N - 1, -1, -1):
        for r in ps[l]:
            bit.add(r)
        for r, i in qs[l]:
            ans[i] = (r - l + 1) - bit.get_sum(r)

    print('\n'.join(map(str, ans)), sep='\n')

    return


if __name__ == '__main__':
    main()

Solution (Python):
import sys

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline


class BIT:
    def __init__(self, n):
        self.n = n
        self.data = [0] * (n + 1)

    def add(self, i, x=1):
        i += 1
        while i <= self.n:
            self.data[i] += x
            i += i & -i

    def get_sum(self, i):
        i += 1
        x = 0
        while i > 0:
            x += self.data[i]
            i -= i & -i
        return x

    
    def get_sum_range(self, l, r):
        return self.get_sum(r - 1) - self.get_sum(l - 1)


def main():
    N, Q = map(int, readline().split())
    C = list(map(int, readline().split()))
    LR = map(int, read().split())

    prev = [-1] * (N + 1)
    ps = [[] for _ in range(N)]
    for i, c in enumerate(C):
        if prev[c] != -1:
            ps[prev[c]].append(i)
        prev[c] = i

    qs = [[] for _ in range(N)]
    for i, (l, r) in enumerate(zip(*[iter(LR)] * 2)):
        qs[l - 1].append((r - 1, i))

    ans = [0] * Q
    bit = BIT(N)

    for l in range(N - 1, -1, -1):
        for r in ps[l]:
            bit.add(r)
        for r, i in qs[l]:
            ans[i] = (r - l + 1) - bit.get_sum(r)

    print('\n'.join(map(str, ans)), sep='\n')

    return


if __name__ == '__main__':
    main()

Solution (Python):
import sys

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60
MOD = 1000000007


class BIT:
    def __init__(self, n):
        self.n = n
        self.data = [0] * (n + 1)

    def add(self, i, x=1):
        i += 1
        while i <= self.n:
            self.data[i] += x
            i += i & -i

    def get_sum(self, i):
        i += 1
        x = 0
        while i > 0:
            x += self.data[i]
            i -= i & -i
        return x

    
    def get_sum_range(self, l, r):
        return self.get_sum(r - 1) - self.get_sum(l - 1)


def main():
    N, Q = map(int, readline().split())
    C = list(map(int, readline().split()))
    LR = map(int, read().split())

    prev = [-1] * (N + 1)
    ps = [[] for _ in range(N)]
    for i, c in enumerate(C):
        if prev[c] != -1:
            ps[prev[c]].append(i)
        prev[c] = i

    qs = [[] for _ in range(N + 1)]
    for i, (l, r) in enumerate(zip(*[iter(LR)] * 2)):
        l -= 1
        r -= 1
        qs[l].append((r, i))

    ans = [0] * Q
    bit = BIT(N)

    for l in range(N - 1, -1, -1):
        for r in ps[l]:
            bit.add(r)
        for r, i in qs[l]:
            ans[i] = (r - l + 1) - bit.get_sum(r)

    print(*ans, sep='\n')

    return


if __name__ == '__main__':
    main()

Solution (Python):
SHIFT = 1 << 20


class fenwick_tree:
    """
    区間の一点更新と，区間和の取得がO(log n)で可能なデータ構造
    1-indexedで実装
    """

    def __init__(self, N):
        self.size = N
        self.tree = [0] * (N+1)

    def sum_until(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & (-i)
        return s

    def sum_acc(self, i, j):
        """ [i,j] の和を返す """
        return self.sum_until(j) - self.sum_until(i-1)

    def add(self, i, x):
        if i <= 0:
            return
        while i <= self.size:
            self.tree[i] += x
            i += i & (-i)


def main():
    N, Q = (int(i) for i in input().split())
    C = [int(i) for i in input().split()]
    Query = []
    for j in range(Q):
        le, ri = (int(i) for i in input().split())
        Query.append(ri << 40 | le << 20 | j)
    Query.sort()

    
    for i in range(Q):
        j = Query[i] % (SHIFT)
        Query[i] >>= 20
        le = Query[i] % (SHIFT)
        Query[i] >>= 20
        ri = Query[i]
        Query[i] = (le, ri, j)
    Query.append((-1, -1, -1))

    lastappend = [-1] * (N + 1)
    bit = fenwick_tree(N)
    idx = 0  
    ans = [0]*Q

    for i, a in enumerate(C, start=1):
        if lastappend[a] != -1:
            bit.add(lastappend[a], -1)
        lastappend[a] = i
        bit.add(i, 1)
        while i == Query[idx][1]:
            (le, ri, j) = Query[idx]
            ans[j] = bit.sum_acc(le, ri)
            idx += 1

    print(*ans, sep="\n")


if __name__ == '__main__':
    main()

Solution (Python):
SHIFT = 1 << 20


def main():
    N, Q = (int(i) for i in input().split())
    C = [int(i) for i in input().split()]
    Query = []
    for j in range(Q):
        le, ri = (int(i) for i in input().split())
        Query.append(ri << 40 | le << 20 | j)
    Query.sort()

    
    for i in range(Q):
        j = Query[i] % (SHIFT)
        Query[i] >>= 20
        le = Query[i] % (SHIFT)
        Query[i] >>= 20
        ri = Query[i]
        Query[i] = (le, ri, j)
    Query.append((-1, -1, -1))

    def sum(tree, i):
        s = 0
        while i > 0:
            s += tree[i]
            i -= i & -i
        return s

    def add(tree, i, x):
        while i <= N:
            tree[i] += x
            i += i & -i

    lastappend = [-1] * (N + 1)
    bit = [0] * (N + 1)
    idx = 0  
    ans = [0]*Q

    for i, a in enumerate(C, start=1):
        if lastappend[a] != -1:
            add(bit, lastappend[a], -1)
        lastappend[a] = i
        add(bit, i, 1)
        while i == Query[idx][1]:
            (le, ri, j) = Query[idx]
            ans[j] = sum(bit, ri) - sum(bit, le-1)
            idx += 1

    print(*ans, sep="\n")


if __name__ == '__main__':
    main()

Solution (Python):
import sys
input = sys.stdin.readline


class BIT:
    def __init__(self, n):
        self.array = [0] * (n + 1)
        self.size = n

    def sum(self, i):
        s = 0
        tmp = i
        while tmp > 0:
            s += self.array[tmp]
            tmp -= tmp & -tmp
        return s

    def add(self, i, x):
        tmp = i + 1
        while tmp <= self.size:
            self.array[tmp] += x
            tmp += tmp & -tmp


n, q = map(int, input().split())
*C, = map(lambda x: int(x) - 1, input().split())
P = [0] * n
N = [None] * n
for i in range(n)[::-1]:
    if P[C[i]]:
        N[i] = P[C[i]]
    P[C[i]] = i
F = [0] * n
B = BIT(n)
for i in range(n):
    if F[C[i]] == 0:
        B.add(i, 1)
        F[C[i]] = 1
XY = [tuple(map(int, input().split())) for j in range(q)]
ids = list(range(q))
ids.sort(key=lambda j: XY[j][0])
a = 0
lst = [0] * q
for j in ids:
    x, y = XY[j]
    for i in range(a, x - 1):
        if N[i]:
            B.add(N[i], 1)
    a = x - 1
    lst[j] = B.sum(y) - B.sum(x - 1)
print(*lst, sep="\n")

Solution (Python):
import sys
import math
from collections import defaultdict

sys.setrecursionlimit(1000000)
MOD = 10 ** 9 + 7
input = lambda: sys.stdin.readline().strip()
NI = lambda: int(input())
NMI = lambda: map(int, input().split())
NLI = lambda: list(NMI())
SI = lambda: input()


def make_grid(h, w, num): return [[int(num)] * w for _ in range(h)]


class BIT():
    def __init__(self, n):
        """
        1-index
        sum -> i番目までの和
        add -> i番目にxを足す
        :param n:
        """
        self.n = n
        self.data = [0]*(n+1)
        self.each = [0]*(n+1)

    def sum(self, i):
        s = 0
        while i > 0:
            s += self.data[i]
            i -= i & -i
        return s

    def add(self, i, x):
        self.each[i] += x
        while i <= self.n:
            self.data[i] += x
            i += i & -i

    def __str__(self):
        return str(self.each)



def main():
    N, Q = NMI()
    C = [0]+NLI()
    d_querys = [[i]+NLI() for i in range(Q)]
    querys = defaultdict(list)
    for qi, ql, qr in d_querys:
        querys[qr].append((qi, ql))

    ans = [0] * Q
    last_index = [-1] * (N+1)
    index_dict = defaultdict(list)
    tree = BIT(N)

    for i, color in enumerate(C):
        if color == 0: continue
        idx = last_index[color]
        if idx != -1:
            index_dict[i].append((idx, i))
        last_index[color] = i
        tree.add(i, 1)

    for i in range(1, N+1):
        for idx, _ in index_dict[i]:
            tree.add(idx, -1)
        for qi, ql in querys[i]:
            ans[qi] = tree.sum(i) - tree.sum(ql-1)

    for a in ans:
        print(a)




if __name__ == "__main__":
    main()

Solution (Python):
from collections import defaultdict
import sys
def read():
    return sys.stdin.readline().rstrip()
def main():
    N, Q = map(int, read().split())
    C = list(map(int, read().split()))
    E = defaultdict(list)

    D = [-1] * (N + 1)
    for i in range(N):
        D_i = D[C[i]]
        if D_i != -1:
            E[D_i].append((D_i, i))
        D[C[i]] = i

    F = defaultdict(list)
    for i in range(Q):
        l, r = map(int, input().split())
        F[l-1].append((r - 1, i))



    
    class BIT:
        def __init__(self, n):
            self.n = n
            self.data = [0] * (n + 1)
            self.el = [0] * (n + 1)

        def sum(self, i):
            s = 0
            while i > 0:
                s += self.data[i]
                i -= i & -i
            return s

        def add(self, i, x):
            
            self.el[i] += x
            while i <= self.n:
                self.data[i] += x
                i += i & -i

        def get(self, i, j=None):
            if j is None:
                return self.el[i]
            return self.sum(j) - self.sum(i)

    ANS = [0] * Q
    d = BIT(N)
    for x in range(N - 1, -1, -1):
        for e in E[x]:
            d.add(e[1], 1)
        for f in F[x]:
            ANS[f[1]] = f[0] - x + 1 - d.sum(f[0])

    for i in range(Q):
        print(ANS[i])

if __name__ == '__main__':
    main()

Solution (Python):
n,q=map(int,input().split())
N=n

data = [0]*(N+1)
def add(k, x):
    while k <= N:
        data[k] += x
        k += k & -k

def get(k):
    s = 0
    while k:
        s += data[k]
        k -= k & -k
    return s

c=[int(i) for i in input().split()]
Q=[]
for i in range(q):
    l,r=map(int,input().split())
    Q.append((l,r,i))
Ans=[0 for i in range(q)]
F=[-1 for i in range(5*10**5+1)]
Q.sort(key=lambda x:x[1])


for i in range(n):
    add(i+1,1)

"""
quen=0
nowQ=Q[quen]
for i in range(n):
    ci=c[i]
    if F[ci]>=0:
        add(F[ci]+1,-1)
    F[ci]=i
    while nowQ[1]==i+1:
        Ans[nowQ[2]]=-get(nowQ[0]-1)+get(nowQ[1])
        quen+=1
        nowQ=Q[quen]
    if nowQ[1]==10**6:
        break
"""

i=0
for nowQ in Q:
    while nowQ[1]!=i:
        ci=c[i]
        if F[ci]>=0:
            add(F[ci]+1,-1)
        F[ci]=i
        i+=1
    Ans[nowQ[2]]=-get(nowQ[0]-1)+get(nowQ[1])


print("\n".join([str(i) for i in Ans]))

Solution (Python):
import sys
input = sys.stdin.readline
from collections import *

class BIT:
    def __init__(self, n):
        self.n = n
        self.bit = [0]*(n+1)
    
    def add(self, i, x):
        i += 1
        
        while i<=self.n:
            self.bit[i] += x
            i += i&(-i)

    def acc(self, i):
        s = 0
        
        while i>0:
            s += self.bit[i]
            i -= i&(-i)
        
        return s

N, Q = map(int, input().split())
c = list(map(int, input().split()))
prev = [-1]*N
ys = defaultdict(list)

for i in range(N):
    if prev[c[i]-1]!=-1:
        ys[prev[c[i]-1]].append(i)
    
    prev[c[i]-1] = i

rs = defaultdict(list)

for i in range(Q):
    l, r = map(int, input().split())
    rs[l-1].append((i, r-1))

bit = BIT(N)
ans = [-1]*Q

for x in range(N-1, -1, -1):
    for y in ys[x]:
        bit.add(y, 1)
    
    for i, r in rs[x]:
        ans[i] = r-x+1-bit.acc(r+1)

for ans_i in ans:
    print(ans_i)

Solution (Python):
import sys
def input(): return sys.stdin.readline().strip()
def mapint(): return map(int, input().split())
sys.setrecursionlimit(10**9)

N, Q = mapint()
Cs = list(mapint())
LR = []
for i in range(Q):
    l, r = mapint()
    k = (r<<40)+(l<<20)+i
    LR.append(k)
LR.sort()
mask = (1<<20)-1
A = [0]*N

def add(A,a,w):
    x = a
    while x <= N:
        A[x-1] += w
        x += x&(-x)

def sums(A,a):
    x = a
    S = 0
    while x != 0:
        S += A[x-1]
        x -= x&(-x)
    return S

ans = [0]*Q
i = 0
last_appeared = [-1]*(N+1)
for k in LR:
    ans_idx = k&mask
    l = (k>>20)&mask
    r = (k>>40)
    while i<r:
        c = Cs[i]
        if last_appeared[c]==-1:
            last_appeared[c] = i+1
            add(A, i+1, 1)
        else:
            past = last_appeared[c]
            last_appeared[c] = i+1
            add(A, past, -1)
            add(A, i+1, 1)
        i += 1
    ans[ans_idx] = sums(A, r)-sums(A, l-1)
for a in ans:
    print(a)

Solution (Python):
import sys
def input(): return sys.stdin.readline().strip()
def mapint(): return map(int, input().split())
sys.setrecursionlimit(10**9)

N, Q = mapint()
Cs = list(mapint())
LR = []
for i in range(Q):
    l, r = mapint()
    k = r*(10**12)+l*(10**6)+i
    LR.append(k)
LR.sort()
A = [0]*N

def add(A,a,w):
    x = a
    while x <= N:
        A[x-1] += w
        x += x&(-x)

def sums(A,a):
    x = a
    S = 0
    while x != 0:
        S += A[x-1]
        x -= x&(-x)
    return S

ans = [0]*Q
i = 0
last_appeared = [-1]*(N+1)
for k in LR:
    ans_idx = k%(10**6)
    l = k//(10**6)%(10**6)
    r = k//(10**12)
    while i<r:
        c = Cs[i]
        if last_appeared[c]==-1:
            last_appeared[c] = i+1
            add(A, i+1, 1)
        else:
            past = last_appeared[c]
            last_appeared[c] = i+1
            add(A, past, -1)
            add(A, i+1, 1)
        i += 1
    ans[ans_idx] = sums(A, r)-sums(A, l-1)
for a in ans:
    print(a)

Solution (Python):
import sys
def input(): return sys.stdin.readline().strip()
def mapint(): return map(int, input().split())
sys.setrecursionlimit(10**9)

N, Q = mapint()
Cs = list(mapint())
LR = []
for i in range(Q):
    l, r = mapint()
    LR.append((l, r, i))
LR.sort(key=lambda x:x[1])
A = [0]*N

def add(A,a,w):
    x = a
    while x <= N:
        A[x-1] += w
        x += x&(-x)

def sums(A,a):
    x = a
    S = 0
    while x != 0:
        S += A[x-1]
        x -= x&(-x)
    return S

ans = [0]*Q
i = 0
last_appeared = [-1]*(N+1)
for l, r, ans_idx in LR:
    while i<r:
        c = Cs[i]
        if last_appeared[c]==-1:
            last_appeared[c] = i+1
            add(A, i+1, 1)
        else:
            past = last_appeared[c]
            last_appeared[c] = i+1
            add(A, past, -1)
            add(A, i+1, 1)
        i += 1
    ans[ans_idx] = sums(A, r)-sums(A, l-1)
for a in ans:
    print(a)

Solution (Python):
import sys
def input(): return sys.stdin.readline().strip()
def mapint(): return map(int, input().split())
sys.setrecursionlimit(10**9)

N, Q = mapint()
Cs = list(mapint())
LR = []
for i in range(Q):
    l, r = mapint()
    LR.append((l, r, i))
LR.sort(key=lambda x:x[1])
A = [0]*N

def add(A,a,w):
    x = a
    while x <= N:
        A[x-1] += w
        x += x&(-x)

def sums(A,a):
    x = a
    S = 0
    while x != 0:
        S += A[x-1]
        x -= x&(-x)
    return S

ans = [0]*Q
idx = 0
dic = {}
for i in range(N):
    c = Cs[i]
    if c not in dic:
        dic[c] = i+1
        add(A, i+1, 1)
    else:
        past = dic[c]
        dic[c] = i+1
        add(A, past, -1)
        add(A, i+1, 1)
    while idx<Q and LR[idx][1]<=i+1:
        l, r, ans_idx = LR[idx]
        ans[ans_idx] = sums(A, r)-sums(A, l-1)
        idx += 1
for a in ans:
    print(a)

Solution (Python):
from operator import itemgetter
import sys


def add(arr, i, size):
    while i < size:
        arr[i] += 1
        i += i & -i


def sub(arr, i, size):
    while i < size:
        arr[i] -= 1
        i += i & -i


def bit_sum(arr, a, b):
    s = 0
    i = b
    while i > 0:
        s += arr[i]
        i -= i & -i
    i = a - 1
    while i > 0:
        s -= arr[i]
        i -= i & -i
    return s


def read():
    return sys.stdin.readline().rstrip()


def main():
    n, q = map(int, read().split())
    c = [int(i) - 1 for i in read().split()]
    queries = [(0, 0, 0) for _ in range(q)]
    for i in range(q):
        l, r = map(int, read().split())
        queries[i] = (i, l, r)
    queries = iter(sorted(queries, key=itemgetter(2)))
    last = [0] * n
    bit = [0] * (n + 1)
    ans = [-1] * q
    k, l, r = next(queries)
    for i in range(n):
        ci = c[i]
        li = last[ci]
        if li > 0:
            sub(bit, li, n + 1)
        last[ci] = i + 1
        add(bit, i + 1, n + 1)
        while i + 1 == r:
            ans[k] = bit_sum(bit, l, r)
            try:
                k, l, r = next(queries)
            except StopIteration:
                print(*ans, sep="\n")
                return


if __name__ == '__main__':
    main()

Solution (Python):
from operator import itemgetter
import sys


class BIT:
    def __init__(self, size: int):
        self.size = size + 1
        self.array = [0] * self.size

    def add(self, i):
        while i < self.size:
            self.array[i] += 1
            i += i & -i

    def sub(self, i):
        while i < self.size:
            self.array[i] -= 1
            i += i & -i

    def sum(self, a, b):
        s = 0
        i = b
        while i > 0:
            s += self.array[i]
            i -= i & -i
        i = a - 1
        while i > 0:
            s -= self.array[i]
            i -= i & -i
        return s


def read():
    return sys.stdin.readline().rstrip()


def main():
    n, q = map(int, read().split())
    c = [int(i) - 1 for i in read().split()]
    queries = [(0, 0, 0) for _ in range(q)]
    for i in range(q):
        l, r = map(int, read().split())
        queries[i] = (i, l, r)
    queries = iter(sorted(queries, key=itemgetter(2)))
    last = [0] * n
    bit = BIT(n)
    ans = [-1] * q
    k, l, r = next(queries)
    for i in range(n):
        ci = c[i]
        li = last[ci]
        if li > 0:
            bit.sub(li)
        last[ci] = i + 1
        bit.add(i + 1)
        while i + 1 == r:
            ans[k] = bit.sum(l, r)
            try:
                k, l, r = next(queries)
            except StopIteration:
                break
    print(*ans, sep="\n")


if __name__ == '__main__':
    main()

Solution (Python):
from operator import itemgetter
import sys


def read():
    return sys.stdin.readline().rstrip()


def add(arr, i):
    while i < len(arr):
        arr[i] += 1
        i += i & -i


def sub(arr, i):
    while i < len(arr):
        arr[i] -= 1
        i += i & -i


def range_sum(arr, a, b):
    s = 0
    i = b
    while i > 0:
        s += arr[i]
        i -= i & -i
    i = a - 1
    while i > 0:
        s -= arr[i]
        i -= i & -i
    return s


def main():
    n, q = map(int, read().split())
    c = [int(i) - 1 for i in read().split()]
    queries = [(0, 0, 0) for _ in range(q)]
    for i in range(q):
        l, r = map(int, read().split())
        queries[i] = (i, l, r)
    queries = iter(sorted(queries, key=itemgetter(2)))
    last = [0] * n
    bit = [0] * (n + 1)
    ans = [-1] * q
    k, l, r = next(queries)
    for i in range(n):
        ci = c[i]
        li = last[ci]
        if li > 0:
            sub(bit, li)
        last[ci] = i + 1
        add(bit, i + 1)
        while i + 1 == r:
            ans[k] = range_sum(bit, l, r)
            try:
                k, l, r = next(queries)
            except StopIteration:
                break
    print(*ans, sep="\n")


if __name__ == '__main__':
    main()

Solution (Python):
from operator import itemgetter
import sys


def read():
    return sys.stdin.readline().rstrip()


def add(arr, i, x):
    while i < len(arr):
        arr[i] += x
        i += i & -i


def range_sum(arr, a, b):
    s = 0
    i = b
    while i > 0:
        s += arr[i]
        i -= i & -i
    i = a - 1
    while i > 0:
        s -= arr[i]
        i -= i & -i
    return s


def main():
    n, q = map(int, read().split())
    c = [int(i) - 1 for i in read().split()]
    queries = [(0, 0, 0) for _ in range(q)]
    for i in range(q):
        l, r = map(int, read().split())
        queries[i] = (i, l, r)
    queries = iter(sorted(queries, key=itemgetter(2)))
    last = [0] * n
    bit = [0] * (n + 1)
    ans = [-1] * q
    k, l, r = next(queries)
    for i in range(n):
        ci = c[i]
        li = last[ci]
        if li > 0:
            add(bit, li, -1)
        last[ci] = i + 1
        add(bit, i + 1, 1)
        while i + 1 == r:
            ans[k] = range_sum(bit, l, r)
            try:
                k, l, r = next(queries)
            except StopIteration:
                break
    print(*ans, sep="\n")


if __name__ == '__main__':
    main()

Solution (Python):
from operator import itemgetter
import sys


def read():
    return sys.stdin.readline().rstrip()


def add(arr, i, x):
    while i < len(arr):
        arr[i] += x
        i += i & -i


def range_sum(arr, a, b):
    s = 0
    i = b
    while i > 0:
        s += arr[i]
        i -= i & -i
    i = a - 1
    while i > 0:
        s -= arr[i]
        i -= i & -i
    return s


def main():
    n, q = map(int, read().split())
    c = [int(i) - 1 for i in read().split()]
    queries = iter(sorted([[i] + [int(j) for j in read().split()] for i in range(q)], key=itemgetter(2)))
    last = [0] * n
    bit = [0] * (n + 1)
    ans = [-1] * q
    k, l, r = next(queries)
    for i in range(n):
        ci = c[i]
        li = last[ci]
        if li > 0:
            add(bit, li, -1)
        last[ci] = i + 1
        add(bit, i + 1, 1)
        while i + 1 == r:
            ans[k] = range_sum(bit, l, r)
            try:
                k, l, r = next(queries)
            except StopIteration:
                break
    print(*ans, sep="\n")


if __name__ == '__main__':
    main()

Solution (Python):
from operator import itemgetter
import sys


class BIT:
    def __init__(self, size: int):
        self.size = size + 1
        self.array = [0] * self.size

    def add(self, i, x):
        if not i > 0:
            return
        while i < self.size:
            self.array[i] += x
            i += i & -i

    def sum(self, i):
        s = 0
        while i > 0:
            s += self.array[i]
            i -= i & -i
        return s


def read():
    return sys.stdin.readline().rstrip()


def main():
    n, q = map(int, read().split())
    c = [int(i) for i in read().split()]
    queries = [() for _ in range(q)]
    for i in range(q):
        l, r = map(int, read().split())
        queries[i] = (i, l, r)
    queries.sort(key=itemgetter(2))
    last = [0] * n
    bit = BIT(n)
    ans = [-1] * q
    cr = 0
    for i, l, r in queries:
        for ri in range(cr, r):
            ci = c[ri] - 1
            bit.add(last[ci], -1)
            last[ci] = ri + 1
            bit.add(last[ci], 1)
            cr = ri
        ans[i] = bit.sum(r) - bit.sum(l - 1)
    print(*ans, sep="\n")


if __name__ == '__main__':
    main()