Buggy python submission (verdict: Time Limit Exceeded):
class ModWorld:
    def __init__(self, mod):
        self.mod = mod

    def prepare_factorial(self, N):
        self.f = [1] # f[n] := n!
        p = 1
        for i in range(1,N+1):
            p = (p*i) % self.mod
            self.f.append(p)

    def modpow(self, x, k):
        x %= self.mod
        k %= self.mod-1 # a^(p-1) = 1
        retval = 1
        while k:
            if k&1: retval = retval * x % self.mod
            k>>=1
            x = x*x % self.mod
        return retval % self.mod

    def modcomb(self, n, k):
        return self.f[n] * self.modpow(self.f[n-k], -1) * self.modpow(self.f[k], -1) % self.mod

mw = ModWorld(mod=10**9+7)

S = input()
nQ_r = S.count('?')
nC_r = S.count('C')
nQ_l = 0
nA_l = 0
N = len(S)
ans = 0
for n, c in enumerate(S):
    if c=='C': nC_r-=1
    if c=='?': nQ_r-=1
    
    if n>0 and n<N-1 and (c=='B' or c=='?'):
        p = ( nQ_l*mw.modpow(3, max(0, nQ_l-1)) + nA_l*mw.modpow(3, nQ_l) ) % mw.mod
        q = ( nQ_r*mw.modpow(3, max(0, nQ_r-1)) + nC_r*mw.modpow(3, nQ_r) ) % mw.mod
        ans += p * q
        ans %= mw.mod

    if c=='A': nA_l+=1
    if c=='?': nQ_l+=1

print(ans)

Fixed submission:
S = input()
nQ_r = S.count('?')
nC_r = S.count('C')
nQ_l = 0
nA_l = 0
N = len(S)
mod = 10**9+7

pow3 = [1]*N
p = 1
for i in range(1,N):
    pow3[i] = p = p*3%mod

ans = 0
for n, c in enumerate(S):
    if c=='C': nC_r-=1
    if c=='?': nQ_r-=1
    
    if n>0 and n<N-1 and (c=='B' or c=='?'):
        p = ( nQ_l*pow3[max(0, nQ_l-1)] + nA_l*pow3[nQ_l] ) % mod
        q = ( nQ_r*pow3[max(0, nQ_r-1)] + nC_r*pow3[nQ_r] ) % mod
        ans += p * q
        ans %= mod

    if c=='A': nA_l+=1
    if c=='?': nQ_l+=1

print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
S = input()
nQ_r = S.count('?')
nC_r = S.count('C')
nQ_l = 0
nA_l = 0
N = len(S)
mod = 10**9+7
ans = 0
for n, c in enumerate(S):
    if c=='C': nC_r-=1
    if c=='?': nQ_r-=1
    
    if n>0 and n<N-1 and (c=='B' or c=='?'):
        p = ( nQ_l*(3**max(0, nQ_l-1) % mod) + nA_l*(3**nQ_l % mod) ) % mod
        q = ( nQ_r*(3**max(0, nQ_r-1) % mod) + nC_r*(3**nQ_r % mod) ) % mod
        ans += p * q
        ans %= mod

    if c=='A': nA_l+=1
    if c=='?': nQ_l+=1

print(ans)

Fixed submission:
S = input()
nQ_r = S.count('?')
nC_r = S.count('C')
nQ_l = 0
nA_l = 0
N = len(S)
mod = 10**9+7

pow3 = [1]*N
p = 1
for i in range(1,N):
    pow3[i] = p = p*3%mod

ans = 0
for n, c in enumerate(S):
    if c=='C': nC_r-=1
    if c=='?': nQ_r-=1
    
    if n>0 and n<N-1 and (c=='B' or c=='?'):
        p = ( nQ_l*pow3[max(0, nQ_l-1)] + nA_l*pow3[nQ_l] ) % mod
        q = ( nQ_r*pow3[max(0, nQ_r-1)] + nC_r*pow3[nQ_r] ) % mod
        ans += p * q
        ans %= mod

    if c=='A': nA_l+=1
    if c=='?': nQ_l+=1

print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
S = input()
nQ_r = S.count('?')
nC_r = S.count('C')
nQ_l = 0
nA_l = 0
N = len(S)
mod = 10**9+7
ans = 0
for n, c in enumerate(S):
    if c=='C': nC_r-=1
    if c=='?': nQ_r-=1
    
    if n>0 and n<N-1 and (c=='B' or c=='?'):
        p = nQ_l*(3**(max(0, nQ_l-1) % (mod-1))) + nA_l*(3**(nQ_l % mod))
        q = nQ_r*(3**(max(0, nQ_r-1) % (mod-1))) + nC_r*(3**(nQ_r % mod))
        ans += p * q
        ans %= mod

    if c=='A': nA_l+=1
    if c=='?': nQ_l+=1

print(ans)

Fixed submission:
S = input()
nQ_r = S.count('?')
nC_r = S.count('C')
nQ_l = 0
nA_l = 0
N = len(S)
mod = 10**9+7

pow3 = [1]*N
p = 1
for i in range(1,N):
    pow3[i] = p = p*3%mod

ans = 0
for n, c in enumerate(S):
    if c=='C': nC_r-=1
    if c=='?': nQ_r-=1
    
    if n>0 and n<N-1 and (c=='B' or c=='?'):
        p = ( nQ_l*pow3[max(0, nQ_l-1)] + nA_l*pow3[nQ_l] ) % mod
        q = ( nQ_r*pow3[max(0, nQ_r-1)] + nC_r*pow3[nQ_r] ) % mod
        ans += p * q
        ans %= mod

    if c=='A': nA_l+=1
    if c=='?': nQ_l+=1

print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
S = input()
nQ_r = S.count('?')
nC_r = S.count('C')
nQ_l = 0
nA_l = 0
N = len(S)
mod = 10**9+7
ans = 0
for n, c in enumerate(S):
    if c=='C': nC_r-=1
    if c=='?': nQ_r-=1
    
    if n>0 and n<N-1 and (c=='B' or c=='?'):
        p = nQ_l*(3**(max(0, nQ_l-1))) + nA_l*(3**nQ_l)
        q = nQ_r*(3**(max(0, nQ_r-1))) + nC_r*(3**nQ_r)
        ans += p * q
        ans %= mod

    if c=='A': nA_l+=1
    if c=='?': nQ_l+=1

print(ans)

Fixed submission:
S = input()
nQ_r = S.count('?')
nC_r = S.count('C')
nQ_l = 0
nA_l = 0
N = len(S)
mod = 10**9+7

pow3 = [1]*N
p = 1
for i in range(1,N):
    pow3[i] = p = p*3%mod

ans = 0
for n, c in enumerate(S):
    if c=='C': nC_r-=1
    if c=='?': nQ_r-=1
    
    if n>0 and n<N-1 and (c=='B' or c=='?'):
        p = ( nQ_l*pow3[max(0, nQ_l-1)] + nA_l*pow3[nQ_l] ) % mod
        q = ( nQ_r*pow3[max(0, nQ_r-1)] + nC_r*pow3[nQ_r] ) % mod
        ans += p * q
        ans %= mod

    if c=='A': nA_l+=1
    if c=='?': nQ_l+=1

print(ans)