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



Sample input:
4 3
1 2 1 3
1 3
2 4
3 3


Sample output:
2
3
1

Submission status: Accepted

Solution code:
def solve():
    import sys
    input = sys.stdin.readline

    class FenwickTree:
        def __init__(self, size):
            self.size = size
            self.array = [0]*size
    
        def add(self, index, value):
            while index < self.size:
                self.array[index] += value
                index += index&(-index)
    
        def sum(self, index):
            answer = 0
            while index > 0:
                answer += self.array[index]
                index -= index&(-index)
            return answer
    
        def rangesum(self, start, end):
            return self.sum(end)-self.sum(start-1)


    N, Q = map(int, input().split())
    *c, = map(int, input().split())
    tree2 = FenwickTree(N+1)
    m = [tuple(map(int, input().split())) for _ in range(Q)]
    idxs = sorted(tuple(range(Q)), key=lambda i: m[i][1])

    right = 0
    pos = [-1] * (N+1)
    ans = [-1] * (Q)

    for idx in idxs:
        l, r = m[idx]
        for i in range(right, r):
            x = pos[c[i]]
            if x != -1:
                tree2.add(x, -1)
            pos[c[i]] = i+1
            tree2.add(i+1, 1)
        ans[idx] = tree2.rangesum(l, r)
        right = r
    for i in ans:
        print(i)


solve()

Submission status: Accepted

Solution code:
class FenwickTree:
    def __init__(self, size):
        self.size = size
        self.array = [0]*size
 
    def add(self, index, value):
        while index < self.size:
            self.array[index] += value
            index += index&(-index)
 
    def sum(self, index):
        answer = 0
        while index > 0:
            answer += self.array[index]
            index -= index&(-index)
        return answer
 
    def rangesum(self, start, end):
        return self.sum(end)-self.sum(start-1)


def solve():
    N, Q = map(int, input().split())
    *c, = map(int, input().split())
    tree2 = FenwickTree(N+1)
    m = [tuple(map(int, input().split())) for _ in range(Q)]
    idxs = sorted(tuple(range(Q)), key=lambda i: m[i][1])

    right = 0
    pos = [-1] * (N+1)
    ans = [-1] * (Q)

    for idx in idxs:
        l, r = m[idx]
        for i in range(right, r):
            x = pos[c[i]]
            if x != -1:
                tree2.add(x, -1)
            pos[c[i]] = i+1
            tree2.add(i+1, 1)
        ans[idx] = tree2.rangesum(l, r)
        right = r
    print(*ans, sep="\n")


if __name__ == '__main__':
    solve()

Submission status: Accepted

Solution code:
class FenwickTree:
    def __init__(self, size):
        self.size = size
        self.array = [0]*size
 
    def add(self, index, value):
        while index < self.size:
            self.array[index] += value
            index += index&(-index)
 
    def sum(self, index):
        answer = 0
        while index > 0:
            answer += self.array[index]
            index -= index&(-index)
        return answer
 
    def rangesum(self, start, end):
        return self.sum(end)-self.sum(start-1)


def solve():
    N, Q = map(int, input().split())
    *c, = map(int, input().split())
    tree2 = FenwickTree(N+1)
    m = [list(map(int, input().split())) for _ in range(Q)]
    idxs = sorted(list(range(Q)), key=lambda i: m[i][1])

    right = 0
    pos = [-1] * (N+1)
    ans = [-1] * (Q)

    for idx in idxs:
        l, r = m[idx]
        for i in range(right, r):
            x = pos[c[i]]
            if x != -1:
                tree2.add(x, -1)
            pos[c[i]] = i+1
            tree2.add(i+1, 1)
        ans[idx] = tree2.rangesum(l, r)
        right = r
    print(*ans, sep="\n")


if __name__ == '__main__':
    solve()

Submission status: Accepted

Solution code:


class FenwickTree:

    def __init__(self, size):
        self.size = size
        self.array = [0]*size

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

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

    def rangesum(self, start, end):
        return self.sum(end)-self.sum(start-1)


def read_int():
    return int(input().strip())


def read_ints():
    return list(map(int, input().split(' ')))

def read_query():
    l, r = read_ints()
    return l-1, r-1

def solve():
    N, Q = read_ints()
    C = [c-1 for c in read_ints()]
    colour_to_index = [-1]*N
    queries = [read_query() for _ in range(Q)]
    answer = [-1]*Q
    queries_sorted_index = sorted(list(range(Q)), key=lambda i: queries[i][1])
    fenwick_tree = FenwickTree(N+1)
    last_r = -1
    for i in queries_sorted_index:
        l, r = queries[i]
        for j in range(last_r+1, r+1):
            colour = C[j]
            if colour_to_index[colour] != -1:
                fenwick_tree.add(colour_to_index[colour]+1, -1)
            colour_to_index[colour] = j
            fenwick_tree.add(colour_to_index[colour]+1, 1)
        answer[i] = fenwick_tree.rangesum(l+1, r+1)
        last_r = r
    print(*answer, sep='\n')


if __name__ == '__main__':
    solve()

Submission status: Accepted

Solution code:


class FenwickTree:

    def __init__(self, size):
        self.size = size
        self.array = [0]*size

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

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

    def rangesum(self, start, end):
        return self.sum(end)-self.sum(start-1)


def read_int():
    return int(input().strip())


def read_ints():
    return list(map(int, input().strip().split(' ')))

def read_query():
    l, r = read_ints()
    return l-1, r-1

def solve():
    N, Q = read_ints()
    C = [c-1 for c in read_ints()]
    colour_to_index = [-1]*N
    queries = [read_query() for _ in range(Q)]
    answer = [-1]*Q
    queries_sorted_index = sorted(list(range(Q)), key=lambda i: queries[i][1])
    fenwick_tree = FenwickTree(N+1)
    last_r = -1
    for i in queries_sorted_index:
        l, r = queries[i]
        for j in range(last_r+1, r+1):
            colour = C[j]
            if colour_to_index[colour] != -1:
                fenwick_tree.add(colour_to_index[colour]+1, -1)
            colour_to_index[colour] = j
            fenwick_tree.add(colour_to_index[colour]+1, 1)
        answer[i] = fenwick_tree.rangesum(l+1, r+1)
        last_r = r
    for a in answer:
        print(a)


if __name__ == '__main__':
    solve()

Submission status: Accepted

Solution code:
import sys
import io, os
input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline

from collections import defaultdict

class BIT:
    def __init__(self, n):
        self.n = n
        self.bit = [0]*(self.n+1) # 1-indexed

    def init(self, init_val):
        for i, v in enumerate(init_val):
            self.add(i, v)

    def add(self, i, x):
        # i: 0-indexed
        i += 1 # to 1-indexed
        while i <= self.n:
            self.bit[i] += x
            i += (i & -i)

    def sum(self, i, j):
        # return sum of [i, j)
        # i, j: 0-indexed
        return self._sum(j) - self._sum(i)

    def _sum(self, i):
        # return sum of [0, i)
        # i: 0-indexed
        res = 0
        while i > 0:
            res += self.bit[i]
            i -= i & (-i)
        return res

class RangeAddBIT:
    def __init__(self, n):
        self.n = n
        self.bit1 = BIT(n)
        self.bit2 = BIT(n)

    def init(self, init_val):
        self.bit2.init(init_val)

    def add(self, l, r, x):
        # add x to [l, r)
        # l, r: 0-indexed
        self.bit1.add(l, x)
        self.bit1.add(r, -x)
        self.bit2.add(l, -x*l)
        self.bit2.add(r, x*r)

    def sum(self, l, r):
        # return sum of [l, r)
        # l, r: 0-indexed
        return self._sum(r) - self._sum(l)

    def _sum(self, i):
        # return sum of [0, i)
        # i: 0-indexed
        return self.bit1._sum(i)*i + self.bit2._sum(i)

def main():

    n, q = map(int, input().split())
    C = list(map(int, input().split()))
    LI = [[] for _ in range(n)]
    for i in range(q):
        l, r = map(int, input().split())
        l, r = l-1, r-1
        LI[r].append((l, i))

    #LR.sort(key=lambda x: x[1])

    bit = RangeAddBIT(n)
    preidx = defaultdict(lambda: -1)
    ans = [-1]*q
    for r in range(n):
        p = preidx[C[r]]
        bit.add(p+1, r+1, 1)
        preidx[C[r]] = r
        for l, i in LI[r]:
            ans[i] = bit.sum(l, l+1)
    print(*ans, sep='\n')

if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.buffer.readline

from collections import defaultdict

class BIT:
    def __init__(self, n):
        self.n = n
        self.bit = [0]*(self.n+1) # 1-indexed

    def init(self, init_val):
        for i, v in enumerate(init_val):
            self.add(i, v)

    def add(self, i, x):
        # i: 0-indexed
        i += 1 # to 1-indexed
        while i <= self.n:
            self.bit[i] += x
            i += (i & -i)

    def sum(self, i, j):
        # return sum of [i, j)
        # i, j: 0-indexed
        return self._sum(j) - self._sum(i)

    def _sum(self, i):
        # return sum of [0, i)
        # i: 0-indexed
        res = 0
        while i > 0:
            res += self.bit[i]
            i -= i & (-i)
        return res

class RangeAddBIT:
    def __init__(self, n):
        self.n = n
        self.bit1 = BIT(n)
        self.bit2 = BIT(n)

    def init(self, init_val):
        self.bit2.init(init_val)

    def add(self, l, r, x):
        # add x to [l, r)
        # l, r: 0-indexed
        self.bit1.add(l, x)
        self.bit1.add(r, -x)
        self.bit2.add(l, -x*l)
        self.bit2.add(r, x*r)

    def sum(self, l, r):
        # return sum of [l, r)
        # l, r: 0-indexed
        return self._sum(r) - self._sum(l)

    def _sum(self, i):
        # return sum of [0, i)
        # i: 0-indexed
        return self.bit1._sum(i)*i + self.bit2._sum(i)

def main():

    n, q = map(int, input().split())
    C = list(map(int, input().split()))
    LI = [[] for _ in range(n)]
    for i in range(q):
        l, r = map(int, input().split())
        l, r = l-1, r-1
        LI[r].append((l, i))

    #LR.sort(key=lambda x: x[1])

    bit = RangeAddBIT(n)
    preidx = defaultdict(lambda: -1)
    ans = [-1]*q
    for r in range(n):
        p = preidx[C[r]]
        bit.add(p+1, r+1, 1)
        preidx[C[r]] = r
        for l, i in LI[r]:
            ans[i] = bit.sum(l, l+1)
    print(*ans, sep='\n')

if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
BIT = [0] * ((1 << 19) + 1)
def add(i, x):
    while i <= (1 << 19):
        BIT[i] += x
        i += i & -i
def query(i):
    res = 0
    while i > 0:
        res += BIT[i]
        i -= i & -i
    return res
n, q = map(int, input().split())
c = list(map(int, input().split()))
Q = [[] for i in range(n)]
for i in range(q):
    l, r = map(int, input().split())
    Q[r - 1].append([l - 1, i])
l = [-1] * n
a = [-1] * q
add(1, n)
for i in range(n):
    add(l[c[i] - 1] + 2, -1)
    add(i + 2, 1)
    l[c[i] - 1] = i
    for j in Q[i]:
        a[j[1]] = query(1 << 19) - query(j[0] + 1)
print(*a, sep="\n")

Submission status: Accepted

Solution code:
def main():
    import sys
    input = sys.stdin.readline
    class BIT:
        def __init__(self,n):
            self.size = n
            self.tree = [0]*(n+1)

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

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

    N,Q = map(int,input().split())
    C = list(map(int,input().split()))
    LR = []
    for i in range(Q):
        l,r = map(int,input().split())
        LR.append((l,r,i))
    bit = BIT(N)
    #color[i] => 色iが最後に登場したインデックス(1-indexed)
    color = [0]*(N+1)

    ANS = [0]*Q
    LR.sort(key=lambda x: x[1])
    cur = 1
    for l,r,j in LR:
        for i in range(cur,r+1):
            c = C[i-1]
            if color[c] != 0:
                bit.add(color[c],-1)
            color[c] = i
            bit.add(i,1)
        cur = r+1
        ANS[j] = bit.sum(r)-bit.sum(l-1)
    for a in ANS:
        print(a)
main()

Submission status: Accepted

Solution code:
import sys
from operator import itemgetter
input = sys.stdin.readline

class BIT:
    def __init__(self, n):
        self.n = n
        self.bit = [0]*(n+1)
        self.value = [0]*(n+1)
    
    def sum(self, i):
        s = 0
        while i > 0:
            s += self.bit[i]
            i -= i & -i
        return s
    
    def add(self, i, x):
        # assert i > 0
        self.value[i] += x
        while i <= self.n:
            self.bit[i] += x
            i += i & -i
    
    def subtract(self, i, x):
        self.add(i, -x)
    
    def init(self, n, lis):
        self.n = n
        self.bit = [0]*(n+1)
        self.value = lis
        for i in range(n):
            self.add(i, lis[i])
            
    def get_value(self, i):
        return self.value[i]
    
    def get_sum(self, i, j):
        return self.sum(j) - self.sum(i)
    
    def lower_bound(self, x):#和がx以上になる最小のインデックス
        if x <= 0:
            return  0
        l, r = 0, self.n
        while r-l > 1:
            index = (r+l)//2
            if self.sum(index) >= x:
                r = index
            else:
                l = index
                
        if self.sum(l) >= x:
            return l
        return r
    
    def upper_bound(self, x):#和がx以下になる最大のインデックス
        if x <= 0:
            return  0
        l, r = 0, self.n
        while r-l > 1:
            index = (r+l)//2
            if self.sum(index) <= x:
                l = index
            else:
                r = index
                
        if self.sum(r) <= x:
            return r
        return l

def main():
    n, q = map(int, input().split())
    c = list(map(int, input().split()))
    query = sorted([list(map(int, input().split())) + [i] for i in range(q)], key=itemgetter(1))
    
    bit = BIT(n)
    index = 0
    already = [0]*(n+1)
    ans = [0]*q
    index = 0
    for l, r, i in query:
        while index < r:
            bit.add(index+1, 1)
            if already[c[index]]:
                bit.subtract(already[c[index]], 1)
            already[c[index]] = index+1
            index += 1
            
        ans[i] = bit.get_sum(l-1, r)

    for a in ans:
        print(a)
        
    
    
    
    
if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
class Bit:
    # Binary Indexed Tree
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)

    def __iter__(self):
        psum = 0
        for i in range(self.size):
            csum = self.sum(i + 1)
            yield csum - psum
            psum = csum
        raise StopIteration()

    def __str__(self):  # O(nlogn)
        return str(list(self))

    def sum(self, i):
        # [0, i) の要素の総和を返す
        if not (0 <= i <= self.size): raise ValueError("error!")
        s = 0
        while i>0:
            s += self.tree[i]
            i -= i & -i
        return s

    def add(self, i, x):
        if not (0 <= i < self.size): raise ValueError("error!")
        i += 1
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

    def __getitem__(self, key):
        if not (0 <= key < self.size): raise IndexError("error!")
        return self.sum(key+1) - self.sum(key)

    def __setitem__(self, key, value):
        # 足し算と引き算にはaddを使うべき
        if not (0 <= key < self.size): raise IndexError("error!")
        self.add(key, value - self[key])

(n, q), c, *d = [[*map(int, o.split())] for o in open(0)]

d = sorted(enumerate(d), key = lambda x: x[1][1])

B = Bit(n)
ans = [-1] * q
last = [-1] * (n + 1)
ind = 0  # [-, ind) まで確認終了
for i, (l, r) in d:
    for j in range(ind, r):
        if last[c[j]] != -1:
            B.add(last[c[j]], -1)
        B.add(j, 1)
        last[c[j]] = j
    ind = r
    ans[i] = B.sum(r) - B.sum(l - 1)
for a in ans:
    print(a)

Submission status: Accepted

Solution code:
import sys

readline = sys.stdin.readline
MOD = 10 ** 9 + 7
INF = float('INF')
sys.setrecursionlimit(10 ** 5)


def main():
    from operator import itemgetter

    class BinaryIndexTree:
        def __init__(self, n):
            self.size = n
            self._container = [0] * (n + 1)
            self.depth = n.bit_length()

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

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

        def lower_bound(self, x):
            if x == 0:
                return 0

            s = 0
            idx = 0
            for i in range(self.depth, -1, -1):
                k = idx + (1 << i)
                if k <= self.size and s + self._container[k] < x:
                    s += self._container[k]
                    idx += 1 << i
            return idx + 1

        def __repr__(self):
            return str(self._container)

    n, q = map(int, readline().split())
    c = [0] + list(map(int, readline().split()))
    query = []
    for i in range(q):
        l, r = map(int, readline().split())
        query.append((l, r, i))

    query.sort(key=itemgetter(1))
    idx = dict()
    cur = 0
    bit = BinaryIndexTree(n)
    res = [0] * q
    s = 0
    for i in range(q):
        l, r, j = query[i]
        while cur < r:
            cur += 1
            color = c[cur]
            if idx.get(color):
                bit.add(idx[color], -1)
            else:
                s += 1
            bit.add(cur, 1)
            idx[color] = cur
        res[j] = s - bit.sum(l - 1)

    for i in range(q):
        print(res[i])


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
def main():
	import sys
	input=sys.stdin.readline
	n,q=map(int,input().split())
	c=list(map(int,input().split()))
	ab=[[]for i in range(n)]
	lr=[[]for i in range(n)]
	num=[-1]*n
	for i in range(n):
		if num[c[i]-1]!=-1:
			ab[num[c[i]-1]].append(i)
		num[c[i]-1]=i
	for i in range(q):
		l,r=map(int,input().split())
		lr[l-1].append((r-1,i))
	ans=[-1]*q
	BIT=[0]*n
	for i in range(n-1,-1,-1):
		for x in ab[i]:
			x+=1
			while x<=n:
				BIT[x-1]+=1
				x=x+(x&-x)
		for x,y in lr[i]:
			X=x
			x+=1
			ret=0
			while x!=0:
				ret+=BIT[x-1]
				x=x-(x&-x)
			ans[y]=X-i+1-ret
	for x in ans:
		print(x)
if __name__ == '__main__':
	main()

Submission status: Accepted

Solution code:
# range set query
from collections import defaultdict
import sys


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


class BIT():
    # 1,,,,,,,Nまでの数値を扱える
    def __init__(self, n):
        self.n = n
        self.data = [0]*(n+1)

    def to_sum(self, i):
        # i番目のところまでのΣ
        s = 0
        while i > 0:
            s += self.data[i]
            i -= (i & -i)
        return s

    def add(self, i, x):
        # i 番目のところに+
        while i <= self.n:
            self.data[i] += x
            i += (i & -i)

    def get(self, i, j):
        # i番目からj番目までの要素のΣ(1<=i<=j<=Nという制約)
        return self.to_sum(j)-self.to_sum(i-1)


que = []
color_data = defaultdict(list)

N, Q = map(int, input().split())
C = list(map(int, input().split()))

for i in range(Q):
    l, r = map(int, input().split())
    que.append((i, l, r))

que.sort(key=lambda x: x[-1])

ans = [-1]*(Q)
previous_color = [-1]*(N+1)

for i, v in enumerate(C):
    color_data[v].append(i+1)

for key in color_data.keys():
    D = color_data[key]
    for i in range(1, len(D)):
        previous_color[D[i]] = D[i-1]

bit_tree = BIT(N)
i0, l0, r0 = que[0]

for _ in range(1, r0+1):
    bit_tree.add(_, 1)
    prev = previous_color[_]
    if prev > 0:
        bit_tree.add(prev, -1)
    ans[i0] = bit_tree.get(l0, r0)

for _ in range(1, Q):
    i, l, r = que[_]
    prv_r = que[_-1][-1]
    for j in range(prv_r+1, r+1):
        bit_tree.add(j, 1)
        prev = previous_color[j]
        if prev > 0:
            bit_tree.add(prev, -1)
    ans[i] = bit_tree.get(l, r)

for x in ans:
    print(x)

Submission status: Accepted

Solution code:
def main():
    import sys
    input = sys.stdin.readline
    class BIT:
        def __init__(self,n):
            self.tree = [0]*(n+1)
            self.size = n
        
        def add(self,i,x):
            while i <= self.size:
                self.tree[i] += x
                i += i&-i
        
        def sum(self,i):
            s = 0
            while i > 0:
                s += self.tree[i]
                i -= i&-i
            return s

    N,Q = map(int,input().split())
    bit = BIT(N)
    C = list(map(int,input().split()))
    query = []
    for i in range(Q):
        l,r = map(int,input().split())
        query.append([l,r,i])
    query.sort(key=lambda x: x[1])
    ans = [0]*Q
    #良い玉のindexを1-indexで管理する
    colorMemo = [0]*(N+1)
    cur = 1
    for q in query:
        l,r,j = q
        #良い玉の情報を更新する
        for i in range(cur,r+1):
            c = C[i-1]
            if colorMemo[c]:
                bit.add(colorMemo[c],-1)
            bit.add(i,1)
            colorMemo[c] = i
        cur = r + 1
        ans[j]=bit.sum(r)-bit.sum(l-1)

    for a in ans:
        print(a)
main()

Submission status: Accepted

Solution code:
class BinaryIndexedTree(object):
    def __init__(self, N):
        self.N = N
        self.bit = [0] * (N + 1)

    def bit_add(self, index, num):
        while (index <= self.N):
            self.bit[index] += num
            index += index & -index
        return

    def bit_sum(self,index):
        result = 0
        while (index > 0):
            result += self.bit[index]
            index -= index & -index
        return result

    def bit_sum_range(self, l, r):
        if (l == r):
            return 1
        else:
            return self.bit_sum(r) - self.bit_sum(l - 1)

def main():
    from sys import stdin
    N, Q = list(map(int, input().split()))
    c = list(map(int, input().split()))
    readline = stdin.readline
    query = [list(map(int, readline().split())) + [i] for i in range(Q)]
    query_result = [0 for i in range(Q)]
    collar_pos = [-1] * (N + 1)
    bit = BinaryIndexedTree(N)

    sorted_query = sorted(query, key=lambda query: query[1])

    index = 1
    for query in sorted_query:
        l, r, q = query
        while (index <= r):
            # update BIT
            if (collar_pos[c[index-1]] != -1):
                bit.bit_add(collar_pos[c[index-1]], -1)
            bit.bit_add(index, 1)
            # update collar_pos
            collar_pos[c[index-1]] = index
            index += 1
        query_result[q] = bit.bit_sum_range(l, r)

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

if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
#!usr/bin/env python3
import sys
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LIR(n):
    return [LI() for i in range(n)]
class BIT:
    def __init__(self, size):
        self.size = size + 1
        self.dat = [0]*self.size

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

    # sum[l,r)
    # sum[0,l] (r = None)
    def sum(self, l, r=None):
        if r is None:
            res = 0
            while l > 0:
                res += self.dat[l]
                l -= l&-l
            return res

        else:
            rres = 0
            while r > 0:
                rres += self.dat[r]
                r -= r&-r
            l -= 1
            lres = 0
            while l > 0:
                lres += self.dat[l]
                l -= l&-l
            return rres - lres


def solve():
    n,Q = LI()
    c = LI()
    q = LIR(Q)
    q = [[i,q[i]] for i in range(Q)]
    q.sort(key = lambda x:x[1][1])
    bit = BIT(n+1)
    i = 0
    p = [None]*(n+1)
    ans = [0]*Q
    for ind,(l, r) in q:
        while i < r:
            ci = c[i]
            j = p[ci]
            if j is not None:
                bit.add(j,-1)
            bit.add(i+1)
            p[ci] = i+1
            i += 1
        ans[ind] = bit.sum(l,r)
    for i in ans:
        print(i)
    return

#Solve
if __name__ == "__main__":
    solve()

Submission status: Accepted

Solution code:
#!usr/bin/env python3
import sys
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LIR(n):
    return [LI() for i in range(n)]
class BIT:
    def __init__(self, size):
        self.size = size + 1
        self.dat = [0]*self.size

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

    # sum[l,r)
    # sum[0,l] (r = None)
    def sum(self, l, r=None):
        if r is None:
            res = 0
            while l > 0:
                res += self.dat[l]
                l -= l&-l
            return res

        else:
            rres = 0
            while r > 0:
                rres += self.dat[r]
                r -= r&-r

            l -= 1
            lres = 0
            while l > 0:
                lres += self.dat[l]
                l -= l&-l

            return rres - lres


def solve():
    n,Q = LI()
    c = LI()
    c = [0]+c
    q = LIR(Q)
    q = [[i,q[i]] for i in range(Q)]
    q.sort(key = lambda x:x[1][1])
    bit = BIT(n+1)
    i = 1
    p = [None]*(n+1)
    ans = [0]*Q
    s = 0
    for ind,(l, r) in q:
        l -= 1
        while i <= r:
            ci = c[i]
            j = p[ci]
            if j is not None:
                bit.add(j)
            else:
                s += 1
            p[ci] = i
            i += 1
        ans[ind] = s-l+bit.sum(l)
    for i in ans:
        print(i)
    return

#Solve
if __name__ == "__main__":
    solve()

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline

N, Q = map(int, input().split())
c = [int(i) for i in input().split()]
lr = [[int(i) - 1 for i in input().split()] for _ in range(Q)]

class BinaryIndexedTree() :
  def __init__(self, n) :
    self.n = n
    self.tree = [0] * (n + 1)
      
  def sum(self, i) :
    s = 0
    while i > 0 :
      s += self.tree[i]
      i -= i & -i
    return s
      
  def add(self, i, x) :
    while i <= self.n :
      self.tree[i] += x
      i += i & -i

BIT = BinaryIndexedTree(N + 5)
sch = [[i, l, r] for i, (l, r) in enumerate(lr)]
sch.sort(key=lambda x: x[2])
ret = [0] * Q
last = [-1] * (N + 1)

cur = 0
for i, l, r in sch :
  while cur <= r :
    BIT.add(cur + 1, 1)
    pos = last[c[cur]]
    if pos != -1 :
      BIT.add(pos + 1, -1)
    last[c[cur]] = cur
    cur += 1
  ret[i] = BIT.sum(r + 1) - BIT.sum(l)
for r in ret :
  print(r)

Submission status: Accepted

Solution code:
import sys,collections as cl,bisect as bs
sys.setrecursionlimit(100000)
input = sys.stdin.readline
mod = 10**9+7
Max = sys.maxsize
def l(): #intのlist
    return list(map(int,input().split()))
def m(): #複数文字
    return map(int,input().split())
def onem(): #Nとかの取得
    return int(input())
def s(x): #圧縮
    a = []
    if len(x) == 0:
        return []
    aa = x[0]
    su = 1
    for i in range(len(x)-1):
        if aa != x[i+1]:
            a.append([aa,su])
            aa = x[i+1]
            su = 1
        else:
            su += 1
    a.append([aa,su])
    return a
def jo(x): #listをスペースごとに分ける
    return " ".join(map(str,x))
def max2(x): #他のときもどうように作成可能
    return max(map(max,x))
def In(x,a): #aがリスト(sorted)
    k = bs.bisect_left(a,x)
    if k != len(a) and a[k] ==  x:
        return True
    else:
        return False

def pow_k(x, n):
    ans = 1
    while n:
        if n % 2:
            ans *= x
        x *= x
        n >>= 1
    return ans

"""
def nibu(x,n,r):
    ll = 0
    rr = r
    while True:
        mid = (ll+rr)//2

    if rr == mid:
        return ll
    if (ここに評価入れる):
        rr = mid
    else:
        ll = mid+1
"""


class SegmentTree:
    def segfunc(self,x,y):
        #ここに評価
        return x + y

    #nは総数、initがlist,ide_eleが元
    def __init__(self,n,init,ide_ele):
        self.n = n
        self.ide_ele = ide_ele
        self.num = 2**(n-1).bit_length()
        self.seg = [ide_ele]*2*self.num
        for i in range(n):
            self.seg[i+self.num-1] = init[i]
        for i in range(self.num-2,-1,-1):
            self.seg[i] = self.segfunc(self.seg[2*i+1],self.seg[2*i+2])
    
    
    def update(self,k,x):
        k += self.num-1
        self.seg[k] += x
        while k:
            k = (k-1)//2
            self.seg[k] = self.segfunc(self.seg[2*k+1],self.seg[2*k+2])
    
    def query(self,p,q):
        if q <= p:
            return self.ide_ele
        p += self.num-1
        q += self.num-2
        res = self.ide_ele
        while q-p > 1:
            if p & 1 == 0:
                res = self.segfunc(res,self.seg[p])
            if q & 1 == 1:
                res = self.segfunc(res,self.seg[q])
                q -= 1
            p //= 2
            q = (q-1)//2
        if p == q:
            res = self.segfunc(res,self.seg[p])
        else:
            res = self.segfunc(self.segfunc(res,self.seg[p]),self.seg[q])
        return res


n,k = m()

Seg = SegmentTree(n,[0 for i in range(n)],0)
a = l()

data = []
for i in range(k):
    po = l()
    po.append(i)
    data.append(po)

data.sort(key = lambda x:x[1])

where = [-1 for i in range(n)]
ans = [0 for i in range(k)]
left = -1
for i in range(k):
    aaa = data[i]
    aaa[0] -= 1
    aaa[1] -= 1
    if aaa[1] > left:
        for j in range(left+1,aaa[1]+1):
            popopo = a[j]-1
            if where[popopo] != -1:
                Seg.update(where[popopo],-1)
            Seg.update(j,1)
            where[popopo] = j
        left = aaa[1]
    ans[aaa[2]] = Seg.query(aaa[0],aaa[1]+1)

for i in range(k):
    print(ans[i])