Buggy python submission (verdict: Time Limit Exceeded):
N,S,Q,*k = open(0).read().split()
N,Q = map(int, (N,Q))
K = map(int, k)
for k in K:
  D = 0
  M = 0
  DM = 0
  DMC = 0
  for i in range(k):
    if S[i]=='D':
      D += 1
    elif S[i]=='M':
      DM += D
      M += 1
    elif S[i]=='C':
      DMC += DM
  for i in range(N-k):
    if S[i]=='D':
      DM -= M
      D -= 1
    elif S[i]=='M':
      M -= 1
    if S[i+k]=='D':
      D += 1
    elif S[i+k]=='M':
      DM += D
      M += 1
    elif S[i+k]=='C':
      DMC += DM
  print(DMC)

Fixed submission:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import numpy as np

N = int(readline())
S = np.frombuffer(readline().rstrip(),'S1')
Q = int(readline())
query = map(int,read().split())

isD = S == b'D'
isM = S == b'M'
isC = S == b'C'

cumD = isD.cumsum(dtype=np.int64)
cumM = isM.cumsum(dtype=np.int64)

def F(K):
    """
    ・Cごとに数える。
    ・そのためには(i-K,i] 内のDMの個数を調べる（負インデックスには関係ない文字があると思っておく）
    ・区間内のDの個数、Mの個数が取得できれば、差分が取得できるので最後に累積和
    """
    # (i-K,i]内のDの個数、Mの個数
    D = cumD.copy(); D[K:] -= cumD[:-K]
    M = cumM.copy(); M[K:] -= cumM[:-K]
    # 最後がMのとき、Dの個数分増える
    DM = isM * D
    # 左端のDを捨てるとき、Mの個数分減る
    DM[K:] -= isD[:-K] * M[K-1:-1]
    np.cumsum(DM,out=DM)
    # Cごとに集計
    return DM[isC].sum()

print('\n'.join(str(F(K)) for K in query))

Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
N,S,Q,*K = open(0).read().split()
N = int(N)
K = map(int,K)
S = np.array(list(S))
C = S=='C'
M = S=='M'
Ms = np.cumsum(M)
for k in K:
  kMs = np.copy(Ms)
  kMs[k:] = Ms[k:] - Ms[:-k]
  CMS = C*kMs
  SDMC = 0
  SMC = 0
  SC = 0
  for i in range(N-1,-1,-1):
    if i<=N-1-k:
      SC -= C[i+k]
      SMC -= CMS[i+k]
    if S[i]=='C':
      SC += 1
    elif S[i]=='M':
      SMC += SC
    elif S[i]=='D':
      SDMC += SMC
  print(SDMC)

Fixed submission:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import numpy as np

N = int(readline())
S = np.frombuffer(readline().rstrip(),'S1')
Q = int(readline())
query = map(int,read().split())

isD = S == b'D'
isM = S == b'M'
isC = S == b'C'

cumD = isD.cumsum(dtype=np.int64)
cumM = isM.cumsum(dtype=np.int64)

def F(K):
    """
    ・Cごとに数える。
    ・そのためには(i-K,i] 内のDMの個数を調べる（負インデックスには関係ない文字があると思っておく）
    ・区間内のDの個数、Mの個数が取得できれば、差分が取得できるので最後に累積和
    """
    # (i-K,i]内のDの個数、Mの個数
    D = cumD.copy(); D[K:] -= cumD[:-K]
    M = cumM.copy(); M[K:] -= cumM[:-K]
    # 最後がMのとき、Dの個数分増える
    DM = isM * D
    # 左端のDを捨てるとき、Mの個数分減る
    DM[K:] -= isD[:-K] * M[K-1:-1]
    np.cumsum(DM,out=DM)
    # Cごとに集計
    return DM[isC].sum()

print('\n'.join(str(F(K)) for K in query))

Buggy python submission (verdict: Time Limit Exceeded):
N,S,Q,*K = open(0).read().split()
N = int(N)
K = map(int,K)
C = [0]*N
M = [0]*N
for i in range(N):
  if S[i]=='C':
    C[i] = 1
  elif S[i]=='M':
    M[i] = 1
for k in K:
  CMS = [0]*N
  SDMC = 0
  SMC = 0
  SC = 0
  Ms = 0
  for i in range(N):
    if i>=k:
      Ms -= M[i-k]
    if S[i]=='C':
      CMS[i] = Ms
    elif S[i]=='M':
      Ms += 1
  for i in range(N-1,-1,-1):
    if i<=N-1-k:
      SC -= C[i+k]
      SMC -= CMS[i+k]
    if S[i]=='C':
      SC += 1
    elif S[i]=='M':
      SMC += SC
    elif S[i]=='D':
      SDMC += SMC
  print(SDMC)

Fixed submission:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import numpy as np

N = int(readline())
S = np.frombuffer(readline().rstrip(),'S1')
Q = int(readline())
query = map(int,read().split())

isD = S == b'D'
isM = S == b'M'
isC = S == b'C'

cumD = isD.cumsum(dtype=np.int64)
cumM = isM.cumsum(dtype=np.int64)

def F(K):
    """
    ・Cごとに数える。
    ・そのためには(i-K,i] 内のDMの個数を調べる（負インデックスには関係ない文字があると思っておく）
    ・区間内のDの個数、Mの個数が取得できれば、差分が取得できるので最後に累積和
    """
    # (i-K,i]内のDの個数、Mの個数
    D = cumD.copy(); D[K:] -= cumD[:-K]
    M = cumM.copy(); M[K:] -= cumM[:-K]
    # 最後がMのとき、Dの個数分増える
    DM = isM * D
    # 左端のDを捨てるとき、Mの個数分減る
    DM[K:] -= isD[:-K] * M[K-1:-1]
    np.cumsum(DM,out=DM)
    # Cごとに集計
    return DM[isC].sum()

print('\n'.join(str(F(K)) for K in query))

Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
N,S,Q,*K = open(0).read().split()
N = int(N)
Q = int(Q)
K = map(int,K)
S = np.array(list(S))
C = S=='C'
M = S=='M'

for k in K:
  CMS = [0]*N
  SDMC = 0
  SMC = 0
  SC = 0
  Ms = 0
  for i in range(N):
    if i>=k:
      Ms -= M[i-k]
    if S[i]=='C':
      CMS[i] = Ms
    elif S[i]=='M':
      Ms += 1
  for i in range(N-1,-1,-1):
    if i<=N-1-k:
      SC -= C[i+k]
      SMC -= CMS[i+k]
    if S[i]=='C':
      SC += 1
    elif S[i]=='M':
      SMC += SC
    elif S[i]=='D':
      SDMC += SMC
  print(SDMC)

Fixed submission:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import numpy as np

N = int(readline())
S = np.frombuffer(readline().rstrip(),'S1')
Q = int(readline())
query = map(int,read().split())

isD = S == b'D'
isM = S == b'M'
isC = S == b'C'

cumD = isD.cumsum(dtype=np.int64)
cumM = isM.cumsum(dtype=np.int64)

def F(K):
    """
    ・Cごとに数える。
    ・そのためには(i-K,i] 内のDMの個数を調べる（負インデックスには関係ない文字があると思っておく）
    ・区間内のDの個数、Mの個数が取得できれば、差分が取得できるので最後に累積和
    """
    # (i-K,i]内のDの個数、Mの個数
    D = cumD.copy(); D[K:] -= cumD[:-K]
    M = cumM.copy(); M[K:] -= cumM[:-K]
    # 最後がMのとき、Dの個数分増える
    DM = isM * D
    # 左端のDを捨てるとき、Mの個数分減る
    DM[K:] -= isD[:-K] * M[K-1:-1]
    np.cumsum(DM,out=DM)
    # Cごとに集計
    return DM[isC].sum()

print('\n'.join(str(F(K)) for K in query))

Buggy python submission (verdict: Time Limit Exceeded):
N,S,Q,*K = open(0).read().split()
N = int(N)
K = map(int,K)
for k in K:
  C = [0]*N
  M = [0]*N
  CMS = [0]*N
  SDMC = 0
  SMC = 0
  SC = 0
  Ms = 0
  for i in range(N):
    if i>=k:
      Ms -= M[i-k]
    if S[i]=='C':
      CMS[i] = Ms
    elif S[i]=='M':
      Ms += 1
      M[i] = 1
  for i in range(N-1,-1,-1):
    if i<=N-1-k:
      SC -= C[i+k]
      SMC -= CMS[i+k]
    if S[i]=='C':
      SC += 1
      C[i] = 1
    elif S[i]=='M':
      SMC += SC
    elif S[i]=='D':
      SDMC += SMC
  print(SDMC)


Fixed submission:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import numpy as np

N = int(readline())
S = np.frombuffer(readline().rstrip(),'S1')
Q = int(readline())
query = map(int,read().split())

isD = S == b'D'
isM = S == b'M'
isC = S == b'C'

cumD = isD.cumsum(dtype=np.int64)
cumM = isM.cumsum(dtype=np.int64)

def F(K):
    """
    ・Cごとに数える。
    ・そのためには(i-K,i] 内のDMの個数を調べる（負インデックスには関係ない文字があると思っておく）
    ・区間内のDの個数、Mの個数が取得できれば、差分が取得できるので最後に累積和
    """
    # (i-K,i]内のDの個数、Mの個数
    D = cumD.copy(); D[K:] -= cumD[:-K]
    M = cumM.copy(); M[K:] -= cumM[:-K]
    # 最後がMのとき、Dの個数分増える
    DM = isM * D
    # 左端のDを捨てるとき、Mの個数分減る
    DM[K:] -= isD[:-K] * M[K-1:-1]
    np.cumsum(DM,out=DM)
    # Cごとに集計
    return DM[isC].sum()

print('\n'.join(str(F(K)) for K in query))

Buggy python submission (verdict: Time Limit Exceeded):
N,S,Q,*K = open(0).read().split()
N = int(N)
K = map(int,K)
for k in K:
  C = [0]*N
  M = [0]*N
  CMS = [0]*N
  SDMC = 0
  SMC = 0
  SC = 0
  Ms = 0
  for i in range(N):
    if i>=k:
      Ms -= M[i-k]
    if S[i]=='C':
      CMS[i] = Ms
    elif S[i]=='M':
      Ms += 1
      M[i] = 1
  for i in range(N-1,-1,-1):
    if i<=N-1-k:
      SC -= C[i+k]
      SMC -= CMS[i+k]
    if S[i]=='C':
      SC += 1
      C[i] = 1
    elif S[i]=='M':
      SMC += SC
    elif S[i]=='D':
      SDMC += SMC
  print(SDMC)


Fixed submission:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import numpy as np

N = int(readline())
S = np.frombuffer(readline().rstrip(),'S1')
Q = int(readline())
query = map(int,read().split())

isD = S == b'D'
isM = S == b'M'
isC = S == b'C'

cumD = isD.cumsum(dtype=np.int64)
cumM = isM.cumsum(dtype=np.int64)

def F(K):
    """
    ・Cごとに数える。
    ・そのためには(i-K,i] 内のDMの個数を調べる（負インデックスには関係ない文字があると思っておく）
    ・区間内のDの個数、Mの個数が取得できれば、差分が取得できるので最後に累積和
    """
    # (i-K,i]内のDの個数、Mの個数
    D = cumD.copy(); D[K:] -= cumD[:-K]
    M = cumM.copy(); M[K:] -= cumM[:-K]
    # 最後がMのとき、Dの個数分増える
    DM = isM * D
    # 左端のDを捨てるとき、Mの個数分減る
    DM[K:] -= isD[:-K] * M[K-1:-1]
    np.cumsum(DM,out=DM)
    # Cごとに集計
    return DM[isC].sum()

print('\n'.join(str(F(K)) for K in query))

Buggy python submission (verdict: Time Limit Exceeded):
N,S,Q,*K = open(0).read().split()
N = int(N)
Q = int(Q)
K = map(int,K)
for k in K:
  C = [0]*N
  M = [0]*N
  CMS = [0]*N
  SDMC = 0
  SMC = 0
  SC = 0
  Ms = 0
  for i in range(k):
    if S[i]=='C':
      CMS[i] = Ms
    elif S[i]=='M':
      Ms += 1
      M[i] = 1
  for i in range(k,N):
    Ms -= M[i-k]
    if S[i]=='C':
      CMS[i] = Ms
    elif S[i]=='M':
      Ms += 1
      M[i] = 1
  for i in range(N-1,N-1-k,-1):
    if S[i]=='C':
      SC += 1
      C[i] = 1
    elif S[i]=='M':
      SMC += SC
    elif S[i]=='D':
      SDMC += SMC
  for i in range(N-1-k,-1,-1):
    SC -= C[i+k]
    SMC -= CMS[i+k]
    if S[i]=='C':
      SC += 1
      C[i] = 1
    elif S[i]=='M':
      SMC += SC
    elif S[i]=='D':
      SDMC += SMC
  print(SDMC)


Fixed submission:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import numpy as np

N = int(readline())
S = np.frombuffer(readline().rstrip(),'S1')
Q = int(readline())
query = map(int,read().split())

isD = S == b'D'
isM = S == b'M'
isC = S == b'C'

cumD = isD.cumsum(dtype=np.int64)
cumM = isM.cumsum(dtype=np.int64)

def F(K):
    """
    ・Cごとに数える。
    ・そのためには(i-K,i] 内のDMの個数を調べる（負インデックスには関係ない文字があると思っておく）
    ・区間内のDの個数、Mの個数が取得できれば、差分が取得できるので最後に累積和
    """
    # (i-K,i]内のDの個数、Mの個数
    D = cumD.copy(); D[K:] -= cumD[:-K]
    M = cumM.copy(); M[K:] -= cumM[:-K]
    # 最後がMのとき、Dの個数分増える
    DM = isM * D
    # 左端のDを捨てるとき、Mの個数分減る
    DM[K:] -= isD[:-K] * M[K-1:-1]
    np.cumsum(DM,out=DM)
    # Cごとに集計
    return DM[isC].sum()

print('\n'.join(str(F(K)) for K in query))

Buggy python submission (verdict: Time Limit Exceeded):
N,S,Q,*K = open(0).read().split()
N = int(N)
Q = int(Q)
K = map(int,K)
for k in K:
  C = [0]*N
  M = [0]*N
  CMS = [0]*N
  SDMC = 0
  SMC = 0
  SC = 0
  Ms = 0
  for i in range(k):
    if S[i]=='C':
      CMS[i] = Ms
    elif S[i]=='M':
      Ms += 1
      M[i] = 1
  for i in range(k,N):
    Ms -= M[i-k]
    if S[i]=='C':
      CMS[i] = Ms
    elif S[i]=='M':
      Ms += 1
      M[i] = 1
  for i in range(N-1,N-1-k,-1):
    if S[i]=='C':
      SC += 1
      C[i] = 1
    elif S[i]=='M':
      SMC += SC
    elif S[i]=='D':
      SDMC += SMC
  for i in range(N-1-k,-1,-1):
    SC -= C[i+k]
    SMC -= CMS[i+k]
    if S[i]=='C':
      SC += 1
      C[i] = 1
    elif S[i]=='M':
      SMC += SC
    elif S[i]=='D':
      SDMC += SMC
  print(SDMC)

Fixed submission:
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import numpy as np

N = int(readline())
S = np.frombuffer(readline().rstrip(),'S1')
Q = int(readline())
query = map(int,read().split())

isD = S == b'D'
isM = S == b'M'
isC = S == b'C'

cumD = isD.cumsum(dtype=np.int64)
cumM = isM.cumsum(dtype=np.int64)

def F(K):
    """
    ・Cごとに数える。
    ・そのためには(i-K,i] 内のDMの個数を調べる（負インデックスには関係ない文字があると思っておく）
    ・区間内のDの個数、Mの個数が取得できれば、差分が取得できるので最後に累積和
    """
    # (i-K,i]内のDの個数、Mの個数
    D = cumD.copy(); D[K:] -= cumD[:-K]
    M = cumM.copy(); M[K:] -= cumM[:-K]
    # 最後がMのとき、Dの個数分増える
    DM = isM * D
    # 左端のDを捨てるとき、Mの個数分減る
    DM[K:] -= isD[:-K] * M[K-1:-1]
    np.cumsum(DM,out=DM)
    # Cごとに集計
    return DM[isC].sum()

print('\n'.join(str(F(K)) for K in query))