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: Time Limit Exceeded

Solution code:
import os
import numpy as np
import sys
input = sys.stdin.readline
print = sys.stdout.write
import numpy as np

def main():
    def bit_add(arr, n, i, x):
        while i <= n:
            arr[i] += x
            i += i & -i

    def bit_sum(arr, i):
        result = 0
        while i > 0:
            result += arr[i]
            i ^= i & -i
        return result

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

    L, R = [], []
    for _ in range(Q):
        l, r = map(int, input().split())
        L.append(l-1);R.append(r-1)

    just_left = {}
    segments = []
    for i in range(N):
        c = C[i]
        if c in just_left:
            segments.append((i, 0, just_left[c], 0))
        just_left[c] = i

    for i in range(Q):
        segments.append((R[i], 1, L[i], i))

    segments.sort()
    bit = np.zeros(N + 2, dtype=np.int64)
    ans = np.zeros(Q, dtype=np.int64)

    for r, tp, l, i in segments:
        if tp == 0:
            bit_add(bit, N + 2, l + 2, 1)
        else:
            base = r - l + 1
            ans[i] = base - (bit_sum(bit, r + 2) - bit_sum(bit, l + 1))

    print("\n".join(map(str,ans)))
main()

Submission status: Time Limit Exceeded

Solution code:
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians, gcd
from itertools import accumulate, permutations, combinations, product, groupby, combinations_with_replacement
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

class Bit:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)
    def sum(self, i):  # 区間 [1, i]の和
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s
    def add(self, i, x):  # iにxを加算
        while i <= self.size:
            self.tree[i] += x
            i += i & -i  
    def pos(self, idx):  # idxの値を取得
        return self.sum(idx) - self.sum(idx-1)
    def lower_bound(self, w):  # w以上の値を持つ最小のidxを検索
        if w <= 0:
            return 0
        idx = 0
        k = 1
        while k*2 <= self.size:
            k *= 2
        while k > 0:
            if idx+k <= self.size and self.tree[idx+k] < w:
                w -= self.tree[idx+k]
                idx += k
            k //= 2
        return idx+1

N, Q = MAP()
c = LIST()
ps = [[] for _ in range(N+1)]
qs = [[] for _ in range(N+1)]
for i in range(Q):
    l, r = MAP()
    qs[l].append((r, i))

checked = [-1]*(N+1)
for i, x in enumerate(c):
    if checked[x] != -1:
        ps[checked[x]].append(i+1)
    checked[x] = i+1

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

for x in range(N, 0, -1):
    for y in ps[x]:
        bit.add(y, 1)
    for r, i in qs[x]:
        ans[i] = r-x+1-bit.sum(r)

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

Submission status: Time Limit Exceeded

Solution code:
import sys

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

in_n = lambda: int(readline())
in_nn = lambda: map(int, readline().split())
in_s = lambda: readline().rstrip().decode('utf-8')
in_nl = lambda: list(map(int, readline().split()))
in_nl2 = lambda H: [in_nl() for _ in range(H)]
in_map = lambda: [s == ord('.') for s in readline() if s != ord('\n')]
in_map2 = lambda H: [in_map() for _ in range(H)]
in_all = lambda: map(int, read().split())


class Bit:

    def __init__(self, a):  # 配列か要素数で初期化
        if hasattr(a, "__iter__"):
            le = len(a)
            self.n = 1 << le.bit_length()
            self.values = values = [0] * (self.n + 1)
            values[1:le + 1] = a[:]
            for i in range(1, self.n):
                values[i + (i & -i)] += values[i]
        elif isinstance(a, int):
            self.n = 1 << a.bit_length()
            self.values = [0] * (self.n + 1)
        else:
            raise TypeError

    def add(self, i, val):  # a[i] += val
        n, values = self.n, self.values
        while i <= n:
            values[i] += val
            i += i & -i

    def sum(self, i):  # (0, i] の累積和
        values = self.values
        res = 0
        while i > 0:
            res += values[i]
            i -= i & -i
        return res

    def bisect_left(self, v):  # 累積和 が v 以上になる最小の i
        n, values = self.n, self.values
        if v > values[n]:
            return None
        i, step = 0, n >> 1
        while step:
            if values[i + step] < v:
                i += step
                v -= values[i]
            step >>= 1
        return i + 1


def main():

    N, Q = in_nn()
    C = in_nl()
    LR = []

    for q in range(Q):
        l, r = in_nn()
        LR.append((r, l, q))

    t = [-1] * (N + 1)
    sect = []
    for i in range(N):
        x = C[i]
        if t[x] != -1:
            sect.append((i + 1, t[x], -1))
        t[x] = i + 1

    sect += LR
    sect.sort(key=lambda x: (x[0], x[2]))

    ans = []
    bit = Bit(N)
    for s in sect:
        r, l, n = s

        if n == -1:
            bit.add(l, 1)
        else:
            t = bit.sum(r) - bit.sum(l - 1)
            ans.append((n, r - l + 1 - t))

    ans.sort()
    for q in range(Q):
        print(ans[q][1])


if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline
print = sys.stdout.write

def main():
    def bit_add(arr, n, i, x):
        while i <= n:
            arr[i] += x
            i += i & -i

    def bit_sum(arr, i):
        result = 0
        while i > 0:
            result += arr[i]
            i ^= i & -i
        return result

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

    L, R = [], []
    for _ in range(Q):
        l, r = map(int, input().split())
        L.append(l-1);R.append(r-1)

    just_left = {}
    segments = []
    for i in range(N):
        c = C[i]
        if c in just_left:
            segments.append((i, 0, just_left[c], 0))
        just_left[c] = i

    for i in range(Q):
        segments.append((R[i], 1, L[i], i))

    segments.sort()
    bit = [0] * (N+2)
    ans = [0] * Q

    for r, tp, l, i in segments:
        if tp == 0:
            bit_add(bit, N + 2, l + 2, 1)
        else:
            base = r - l + 1
            ans[i] = base - (bit_sum(bit, r + 2) - bit_sum(bit, l + 1))

    print("\n".join(map(str,ans)))
main()

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline
print = sys.stdout.write

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

def bit_sum(arr, i):
    result = 0
    while i > 0:
        result += arr[i]
        i ^= i & -i
    return result

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

L, R = [], []
for _ in range(Q):
    l, r = map(int, input().split())
    L.append(l-1);R.append(r-1)
    
just_left = {}
segments = []
for i in range(N):
    c = C[i]
    if c in just_left:
        segments.append((i, 0, just_left[c], 0))
    just_left[c] = i

for i in range(Q):
    segments.append((R[i], 1, L[i], i))

segments.sort()
bit = [0] * (N+2)
ans = [0] * Q

for r, tp, l, i in segments:
    if tp == 0:
        bit_add(bit, N + 2, l + 2, 1)
    else:
        base = r - l + 1
        ans[i] = base - (bit_sum(bit, r + 2) - bit_sum(bit, l + 1))

print("\n".join(map(str,ans)))

Submission status: Time Limit Exceeded

Solution code:
from collections import deque

def make_tree(n):
    i = 2
    while True:
        if i >= n * 2:
            tree = [0] * i
            break
        else:
            i *= 2
    return tree

def update(i, x):
    i += lt // 2
    tree[i] = x
    i //= 2
    while True:
        if i == 0:
            break
        tree[i] = tree[2 * i] + tree[2 * i + 1]
        i //= 2
    return

def getsum(s, t):
    s += lt // 2
    t += lt // 2
    ans = 0
    while True:
        if s > t:
            break
        if s % 2 == 0:
            s //= 2
        else:
            ans = ans + tree[s]
            s = (s + 1) // 2
        if t % 2 == 1:
            t //= 2
        else:
            ans = ans + tree[t]
            t = (t - 1) // 2
    return ans

n, q = map(int, input().split())
c = list(map(int, input().split()))
cc = [0] * (n + 1)
tree = make_tree(n)
lt = len(tree)
a = [deque() for _ in range(n)]
for i in range(n):
    if cc[c[i]] == 0:
        update(i, 1)
        cc[c[i]] = 1
    else:
        a[c[i] - 1].append(i)
x = [0] * q
for i in range(q):
    l, r = map(int, input().split())
    x[i] = [l - 1, r - 1, i]
#print(x)
x.sort()
u = 0
xx = [0] * q
for i in range(q):
    for j in range(u, x[i][0]):
        if tree[lt // 2 + j] == 1:
            if a[c[j] - 1]:
                update(a[c[j] - 1].popleft(), 1)
            update(j, 0)
    u = x[i][0]
    xx[x[i][2]] = getsum(x[i][0], x[i][1])
    #print(tree)
for i in xx:
    print(i)

Submission status: Time Limit Exceeded

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

N,Q=map(int,input().split())
C=[0]+list(map(int,input().split()))

QU=[list(map(int,input().split()))+[i] for i in range(Q)]


QU.sort(key=itemgetter(0))

NUM=[[] for i in range(N+1)]
for i,c in enumerate(C):
    NUM[c].append(i)
NUMIND=[0]*(N+1)

# BIT(BIT-indexed tree)

LEN=N+3

BIT=[0]*(LEN+1) # 1-indexedなtree

def update(v,w): # index vにwを加える
    while v<=LEN:
        BIT[v]+=w
        v+=(v&(-v)) # 自分を含む大きなノードへ. たとえばv=3→v=4

def getvalue(v): # [1,v]の区間の和を求める
    ANS=0
    while v!=0:
        ANS+=BIT[v]
        v-=(v&(-v)) # 自分より小さい2ベキのノードへ. たとえばv=3→v=2へ
    return ANS

for x in NUM[1:]:
    if x:
        update(x[0],1)

ANS=[-1]*Q

ia=1

for x,y,ind in QU:

    while ia!=x:
        update(NUM[C[ia]][NUMIND[C[ia]]],-1)
        NUMIND[C[ia]]+=1
        if NUMIND[C[ia]]<len(NUM[C[ia]]):
            update(NUM[C[ia]][NUMIND[C[ia]]],1)
        ia+=1

    #print(x,y,ind)
    #print([getvalue(i) for i in range(1,N+1)])
    ANS[ind]=getvalue(y)

sys.stdout.write(" ".join(map(str,ANS))+"\n")

Submission status: Time Limit Exceeded

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

N,Q=map(int,input().split())
C=[0]+list(map(int,input().split()))

QU=[list(map(int,input().split()))+[i] for i in range(Q)]


QU.sort(key=itemgetter(0))

NUM=[[] for i in range(N+1)]
for i,c in enumerate(C):
    NUM[c].append(i)
NUMIND=[0]*(N+1)

# BIT(BIT-indexed tree)

LEN=N+3

BIT=[0]*(LEN+1) # 1-indexedなtree

def update(v,w): # index vにwを加える
    while v<=LEN:
        BIT[v]+=w
        v+=(v&(-v)) # 自分を含む大きなノードへ. たとえばv=3→v=4

def getvalue(v): # [1,v]の区間の和を求める
    ANS=0
    while v!=0:
        ANS+=BIT[v]
        v-=(v&(-v)) # 自分より小さい2ベキのノードへ. たとえばv=3→v=2へ
    return ANS

for x in NUM[1:]:
    if x:
        update(x[0],1)

ANS=[-1]*Q

ia=1

for x,y,ind in QU:

    while ia!=x:
        update(NUM[C[ia]][NUMIND[C[ia]]],-1)
        NUMIND[C[ia]]+=1
        if NUMIND[C[ia]]<len(NUM[C[ia]]):
            update(NUM[C[ia]][NUMIND[C[ia]]],1)
        ia+=1

    #print(x,y,ind)
    #print([getvalue(i) for i in range(1,N+1)])
    ANS[ind]=getvalue(y)

print(*ANS)

Submission status: Time Limit Exceeded

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

N,Q=map(int,input().split())
C=[0]+list(map(int,input().split()))

QU=[list(map(int,input().split()))+[i] for i in range(Q)]


QU.sort(key=itemgetter(0))

NUM=[[] for i in range(N+1)]
for i,c in enumerate(C):
    NUM[c].append(i)
NUMIND=[0]*(N+1)

# BIT(BIT-indexed tree)

LEN=N+3

BIT=[0]*(LEN+1) # 1-indexedなtree

def update(v,w): # index vにwを加える
    while v<=LEN:
        BIT[v]+=w
        v+=(v&(-v)) # 自分を含む大きなノードへ. たとえばv=3→v=4

def getvalue(v): # [1,v]の区間の和を求める
    ANS=0
    while v!=0:
        ANS+=BIT[v]
        v-=(v&(-v)) # 自分より小さい2ベキのノードへ. たとえばv=3→v=2へ
    return ANS

for x in NUM[1:]:
    if x:
        update(x[0],1)

ANS=[-1]*Q

ia=1

for x,y,ind in QU:

    while ia!=x:
        update(NUM[C[ia]][NUMIND[C[ia]]],-1)
        NUMIND[C[ia]]+=1
        if NUMIND[C[ia]]<len(NUM[C[ia]]):
            update(NUM[C[ia]][NUMIND[C[ia]]],1)
        ia+=1

    #print(x,y,ind)
    #print([getvalue(i) for i in range(1,N+1)])
    ANS[ind]=getvalue(y)

print(*ANS)

Submission status: Time Limit Exceeded

Solution code:
n, q = map(int, input().split())
list_c = list(map(int, input().split()))

for idx in range(q):
  l, r = map(int, input().split())
  temp_list = list_c[(l-1):r]
  print(len(set(temp_list)))

Submission status: Time Limit Exceeded

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

N,Q=map(int,input().split())
C=[0]+list(map(int,input().split()))

QU=[list(map(int,input().split()))+[i] for i in range(Q)]

from operator import itemgetter
QU.sort(key=itemgetter(0))

from collections import deque

NUM=[[] for i in range(N+1)]
for i,c in enumerate(C):
    NUM[c].append(i)
NUMIND=[0]*(N+1)

# BIT(BIT-indexed tree)

LEN=N+3

BIT=[0]*(LEN+1) # 1-indexedなtree

def update(v,w): # index vにwを加える
    while v<=LEN:
        BIT[v]+=w
        v+=(v&(-v)) # 自分を含む大きなノードへ. たとえばv=3→v=4

def getvalue(v): # [1,v]の区間の和を求める
    ANS=0
    while v!=0:
        ANS+=BIT[v]
        v-=(v&(-v)) # 自分より小さい2ベキのノードへ. たとえばv=3→v=2へ
    return ANS

for x in NUM[1:]:
    if x:
        update(x[0],1)

ANS=[-1]*Q

ia=1

for x,y,ind in QU:

    while ia!=x:
        update(NUM[C[ia]][NUMIND[C[ia]]],-1)
        NUMIND[C[ia]]+=1
        if NUMIND[C[ia]]<len(NUM[C[ia]]):
            update(NUM[C[ia]][NUMIND[C[ia]]],1)
        ia+=1

    #print(x,y,ind)
    #print([getvalue(i) for i in range(1,N+1)])
    ANS[ind]=getvalue(y)

print(*ANS)

Submission status: Time Limit Exceeded

Solution code:
import math
import sys
sys.setrecursionlimit(10**6)
def query(tree,index,s,e,qs,qe):
    #no overlap
    if(qe<s or qs>e):
        return []

    # complete overlap
    if(qs<=s and qe>=e):
        return tree[index]

    #partial overlap
    mid=s+(e-s)//2
    return query(tree,index*2+1,s,mid,qs,qe)+query(tree,index*2+2,mid+1,e,qs,qe)

def build(arr,tree,index,s,e):
    #print(tree)
    if(s==e):
        tree[index]=tree[index]+[arr[s]]
        return [arr[s]]
    mid=s+(e-s)//2
    tree[index]=build(arr,tree,index*2+1,s,mid)+build(arr,tree,index*2+2,mid+1,e)
    return tree[index]

n,q=map(int, input().split())
arr=list(map(int,input().split()))
l=len(arr)
x=int(math.ceil(math.log2(l)))
maxsize=2*(2**x)-1
tree=[[]]*maxsize

build(arr,tree,0,0,l -1)
#print(tree)
for i in range(q):
    x,y=map(int, input().split())
    v=query(tree,0,0,l-1,x-1,y-1)
    print(len(set(v)))

Submission status: Time Limit Exceeded

Solution code:
import io
import os


# Mo's algorithm for counting distinct in a range
# O(N*sqrt(N)), TLEs on 5*10**5
# From https://www.geeksforgeeks.org/mos-algorithm-query-square-root-decomposition-set-1-introduction/
def solve(N, Q, C, L, R):
    # Mo's order, first by block, then zigzag depending of parity of block
    MAX_R = 1 << 20

    def moOrder(i):
        l, r = L[i], R[i]
        b = l >> 10  # Block size of 1024
        r = (MAX_R - r) if b % 2 else r  # Decreasing r if block odd
        # assert 0 <= y < MAX_R
        return b * MAX_R + r

    order = sorted(range(Q), key=moOrder)

    currL, currR = 0, 0
    countUniq = [0 for i in range(N + 1)]
    numUniq = 0

    ans = [0 for i in range(Q)]
    for i in order:
        l, r = L[i], R[i]

        while currR <= r:
            x = C[currR]
            numUniq += int(countUniq[x] == 0)
            countUniq[x] += 1
            currR += 1
        while currR > r + 1:
            x = C[currR - 1]
            countUniq[x] -= 1
            numUniq -= int(countUniq[x] == 0)
            currR -= 1
        while currL < l:
            x = C[currL]
            countUniq[x] -= 1
            numUniq -= int(countUniq[x] == 0)
            currL += 1
        while currL > l:
            x = C[currL - 1]
            numUniq += int(countUniq[x] == 0)
            countUniq[x] += 1
            currL -= 1

        # assert len([i for i, x in enumerate(countUniq) if x > 0]) == numUniq
        # print(C[L : R + 1], "is", [i for i, x in enumerate(countUniq) if x > 0], numUniq)
        ans[i] = numUniq
    return "\n".join(map(str, ans))


if False:
    import random

    random.seed(0)
    N = 5 * 10 ** 5
    Q = 5 * 10 ** 5
    C = [random.randint(1, N) for i in range(N)]
    L = []
    R = []
    for i in range(Q):
        l = random.randint(0, N - 1)
        r = random.randint(0, N - 1)
        if l > r:
            l, r = r, l
        L.append(l)
        R.append(r)
    solve(N, Q, C, L, R)
    exit()


if __name__ == "__main__":
    input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

    N, Q = [int(x) for x in input().split()]
    C = [int(x) for x in input().split()]
    L = []
    R = []
    for i in range(Q):
        # 0-indexed, inclusive inclusive
        l, r = [int(x) - 1 for x in input().split()]
        L.append(l)
        R.append(r)
    print(solve(N, Q, C, L, R))

Submission status: Time Limit Exceeded

Solution code:
import os
import heapq as h
import sys
import math
import operator
from collections import defaultdict
from io import BytesIO, IOBase


"""def gcd(a,b):
    if b==0:
        return a
    else:
        return gcd(b,a%b)"""

"""def pw(a,b):
    result=1
    while(b>0):
        if(b%2==1): result*=a
        a*=a
        b//=2
    return result"""



def inpt():
    return [int(k) for k in input().split()]


def queryResults(arr, Q):

    Q.sort(key=lambda x: x[1])
    currL, currR= 0, 0
    d=defaultdict(int)
    ans=[]
    for i in range(len(Q)):
        L, R ,P = Q[i]

        while currL < L:
            d[arr[currL]]-=1
            if(d[arr[currL]]==0):
                d.pop(arr[currL])
            currL += 1

        while currL > L:
            d[arr[currL - 1]]+=1
            if (d[arr[currL-1]] == 0):
                d.pop(arr[currL-1])
            currL -= 1

        while currR <= R:
            d[arr[currR]]+=1
            if (d[arr[currR]] == 0):
                d.pop(arr[currR])
            currR += 1

        while currR > (R + 1):
            d[arr[currR-1]] -= 1
            if (d[arr[currR-1]] == 0):
                d.pop(arr[currR-1])
            currR -= 1

        ans.append((P,len(d)))
    return ans



def main():
    n,q=map(int,input().split())
    ar=inpt()
    Q=[]
    for i in range(q):
        a,b=map(int,input().split())
        Q.append((a-1,b-1,i))
    ans=queryResults(ar, Q)
    ans.sort()
    for i in ans:
        print(i[1])

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)


class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")


sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

if __name__ == "__main__":
    main()

Submission status: Time Limit Exceeded

Solution code:
import sys

input = sys.stdin.buffer.readline
n, q = map(int, input().split())
C = list(map(int, input().split()))


def popcnt(n):
    c = (n & 0x5555555555555555) + ((n >> 1) & 0x5555555555555555)
    c = (c & 0x3333333333333333) + ((c >> 2) & 0x3333333333333333)
    c = (c & 0x0F0F0F0F0F0F0F0F) + ((c >> 4) & 0x0F0F0F0F0F0F0F0F)
    c = (c & 0x00FF00FF00FF00FF) + ((c >> 8) & 0x00FF00FF00FF00FF)
    c = (c & 0x0000FFFF0000FFFF) + ((c >> 16) & 0x0000FFFF0000FFFF)
    c = (c & 0x00000000FFFFFFFF) + ((c >> 32) & 0x00000000FFFFFFFF)
    return c


num = 2 ** ((n - 1).bit_length())
SEG = [0] * (2 * num)


def func(a, b):
    return a | b


for idx, val in enumerate(C):
    idx += num
    SEG[idx] = 1 << (val - 1)
for idx in range(num - 1, 0, -1):
    while idx > 0:
        SEG[idx] = func(SEG[2 * idx], SEG[2 * idx + 1])
        idx //= 2


def query(left, right):
    resleft = 0
    resright = 0
    left += num
    right += num
    while right - left > 0:
        if left % 2 == 1:
            resleft = func(resleft, SEG[left])
            left += 1
        if right % 2 == 1:
            right -= 1
            resright = func(resright, SEG[right])
        left //= 2
        right //= 2
    return func(resleft, resright)


for _ in range(q):
    l, r = map(int, input().split())
    temp = query(l - 1, r)
    print(popcnt(temp))

Submission status: Time Limit Exceeded

Solution code:
def main():
    import sys
    def MI():
        return map(int, sys.stdin.readline().rstrip().split())
    def LI():
        return list(map(int, sys.stdin.readline().rstrip().split()))  # 空白あり

    N,Q = MI()
    c = [0] + LI()
    lr = []
    for i in range(Q):
        l,r = MI()
        lr.append((r,l,i))

    lr.sort()  # 右端rでソート
    a = 0
    d = {}  # d[i] = 玉iが現れた最も右の位置
    ANS = [0]*Q


    class BIT():
        def __init__(self, init_value):
            self.n = len(init_value)
            self.tree = [0] * (self.n + 1)
            for i in range(1, self.n + 1):
                x = init_value[i - 1]
                while i <= self.n:
                    self.tree[i] += x
                    i += i & (-i)

        def update(self, i, x):  # i(1-index)番目の値を+x
            while i <= self.n:
                self.tree[i] += x
                i += i & (-i)
            return

        def query(self, i):  # 1番目からi(1-index)番目までの和を返す
            res = 0
            while i > 0:
                res += self.tree[i]
                i -= i & (-i)
            return res


    bit = BIT([0]*N)  # 最も右に現れた玉の位置を管理
    for i in range(1,N+1):
        if not c[i] in d.keys():
            d[c[i]] = i
            bit.update(i,1)
        else:
            bit.update(d[c[i]],-1)
            d[c[i]] = i
            bit.update(i, 1)
        while a <= Q-1 and lr[a][0] == i:
            r,l,j = lr[a]
            ANS[j] = bit.query(r)-bit.query(l-1)
            a += 1

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


if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
Bsize = 800

def main():
    import sys
    input = sys.stdin.buffer.readline

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

    query_list = [[] for _ in range(N // Bsize + 1)]
    for q in range(Q):
        l, r = map(int, input().split())
        query_list[(l-1) // Bsize].append((l - 1, r - 1, q))
    for i in range(N // Bsize + 1):
        if query_list[i]:
            if i&1:
                query_list[i].sort(key=lambda x: x[1], reverse=True)
            else:
                query_list[i].sort(key=lambda x: x[1])
    query = []
    for ql in query_list:
        query.extend(ql)

    # [l, r)での求める値を管理するための変数たち
    # 問題によって変える
    cnt = [0] * (N + 1)
    val = 0

    # 区間の伸縮操作
    # 問題によって変える
    def add(i):
        nonlocal val
        if not cnt[A[i]]:
            val += 1
        cnt[A[i]] += 1

    def rem(i):
        nonlocal val
        cnt[A[i]] -= 1
        if not cnt[A[i]]:
            val -= 1

    # init
    l, r, _ = query[0]
    for i in range(l, r + 1):
        add(i)

    # process
    ans = [0] * Q
    for l_new, r_new, q in query:
        if r < r_new:
            for i in range(r + 1, r_new + 1):
                add(i)
        elif r > r_new:
            for i in range(r, r_new, -1):
                rem(i)
        if l < l_new:
            for i in range(l, l_new):
                rem(i)
        elif l > l_new:
            for i in range(l - 1, l_new - 1, -1):
                add(i)
        l = l_new
        r = r_new
        ans[q] = val

    for a in ans:
        print(a)


if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
mod = 1000000007
eps = 10**-9
Bsize = 1000

def main():
    import sys
    input = sys.stdin.buffer.readline

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

    query_list = [[] for _ in range(N // Bsize + 1)]
    for q in range(Q):
        l, r = map(int, input().split())
        query_list[(l-1) // Bsize].append((l - 1, r - 1, q))
    for i in range(N // Bsize + 1):
        if query_list[i]:
            if i&1:
                query_list[i].sort(key=lambda x: x[1], reverse=True)
            else:
                query_list[i].sort(key=lambda x: x[1])
    query = []
    for ql in query_list:
        query.extend(ql)

    # [l, r)での求める値を管理するための変数たち
    # 問題によって変える
    cnt = [0] * (N + 1)
    val = 0

    # 区間の伸縮操作
    # 問題によって変える
    def add(i):
        nonlocal val
        cnt[A[i]] += 1
        if cnt[A[i]] == 1:
            val += 1

    def rem(i):
        nonlocal val
        cnt[A[i]] -= 1
        if cnt[A[i]] == 0:
            val -= 1

    # init
    l, r, _ = query[0]
    for i in range(l, r + 1):
        add(i)

    # process
    ans = [0] * Q
    for l_new, r_new, q in query:
        if r < r_new:
            for i in range(r + 1, r_new + 1):
                add(i)
        elif r > r_new:
            for i in range(r, r_new, -1):
                rem(i)
        if l < l_new:
            for i in range(l, l_new):
                rem(i)
        elif l > l_new:
            for i in range(l - 1, l_new - 1, -1):
                add(i)
        l = l_new
        r = r_new
        ans[q] = val

    for a in ans:
        print(a)


if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
mod = 1000000007
eps = 10**-9
Bsize = 800

def main():
    import sys
    input = sys.stdin.buffer.readline

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

    query_list = [[] for _ in range(N // Bsize + 1)]
    for q in range(Q):
        l, r = map(int, input().split())
        query_list[(l-1) // Bsize].append((l - 1, r - 1, q))
    for i in range(N // Bsize + 1):
        if query_list[i]:
            if i&1:
                query_list[i].sort(key=lambda x: x[1], reverse=True)
            else:
                query_list[i].sort(key=lambda x: x[1])
    query = []
    for ql in query_list:
        query.extend(ql)

    # [l, r)での求める値を管理するための変数たち
    # 問題によって変える
    cnt = [0] * (N + 1)
    val = 0

    # 区間の伸縮操作
    # 問題によって変える
    def add(i):
        nonlocal val
        cnt[A[i]] += 1
        if cnt[A[i]] == 1:
            val += 1

    def rem(i):
        nonlocal val
        cnt[A[i]] -= 1
        if cnt[A[i]] == 0:
            val -= 1

    # init
    l, r, _ = query[0]
    for i in range(l, r + 1):
        add(i)

    # process
    ans = [0] * Q
    for l_new, r_new, q in query:
        if r < r_new:
            for i in range(r + 1, r_new + 1):
                add(i)
        elif r > r_new:
            for i in range(r, r_new, -1):
                rem(i)
        if l < l_new:
            for i in range(l, l_new):
                rem(i)
        elif l > l_new:
            for i in range(l - 1, l_new - 1, -1):
                add(i)
        l = l_new
        r = r_new
        ans[q] = val

    for a in ans:
        print(a)


if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
def main():
    import sys
    def MI():
        return map(int, sys.stdin.readline().rstrip().split())
    def LI():
        return list(map(int, sys.stdin.readline().rstrip().split()))  # 空白あり

    N,Q = MI()
    c = [0] + LI()
    lr = []
    for i in range(Q):
        l,r = MI()
        lr.append((i,l,r))

    from operator import itemgetter

    lr = sorted(lr,key=itemgetter(2))  # 右端rでソート
    a = 0
    d = {}  # d[i] = 玉iが現れた最も右の位置
    ANS = []


    class BIT():
        def __init__(self, init_value):
            self.n = len(init_value)
            self.tree = [0] * (self.n + 1)
            for i in range(1, self.n + 1):
                x = init_value[i - 1]
                while i <= self.n:
                    self.tree[i] += x
                    i += i & (-i)

        def update(self, i, x):  # i(1-index)番目の値を+x
            while i <= self.n:
                self.tree[i] += x
                i += i & (-i)
            return

        def query(self, i):  # 1番目からi(1-index)番目までの和を返す
            res = 0
            while i > 0:
                res += self.tree[i]
                i -= i & (-i)
            return res


    bit = BIT([0]*N)  # 最も右に現れた玉の位置を管理
    for i in range(1,N+1):
        if not c[i] in d.keys():
            d[c[i]] = i
            bit.update(i,1)
        else:
            bit.update(d[c[i]],-1)
            d[c[i]] = i
            bit.update(i, 1)
        while a <= Q-1 and lr[a][2] == i:
            j,l,r = lr[a]
            ANS.append((j,bit.query(r)-bit.query(l-1)))
            a += 1

    ANS.sort()
    print(*[ANS[i][1] for i in range(Q)],sep='\n')


if __name__ == '__main__':
    main()