Buggy python submission (verdict: Time Limit Exceeded):
# -*- coding: utf-8 -*-
s = list(input())
# from random import randrange
# s = [["A","B","C","?"][randrange(4)] for _ in range(10**5)]
n = len(s)
MOD = 10**9 + 7

def modpow(a,n,m):
    res = 1
    while n>0:
        if n%2==1:
            res = (res * a) % m
        a = (a*a) % m
        n = n//2
    return res

al = [0]*(n+1)
bl = [0]*(n+1)
cl = [0]*(n+1)
ql = [0]*(n+1)
for i in range(n):
    if s[i]=="A":
        al[i+1] += 1
    elif s[i]=="B":
        bl[i+1] += 1
    elif s[i]=="C":
        cl[i+1] += 1
    else:
        ql[i+1] += 1

    al[i+1] += al[i]
    bl[i+1] += bl[i]
    cl[i+1] += cl[i]
    ql[i+1] += ql[i]

res = 0
for i in range(n):
    if s[i]=="A" or s[i]=="C":
        continue

    res += (al[i]-al[0])*(cl[n]-cl[i+1])*modpow(3,(ql[i]-ql[0] + ql[n]-ql[i+1]),MOD)
    res %= MOD
    res += (al[i]-al[0])*(ql[n]-ql[i+1])*modpow(3,(ql[i]-ql[0] + ql[n]-ql[i+1]-1),MOD)
    res %= MOD
    res += (ql[i]-ql[0])*(cl[n]-cl[i+1])*modpow(3,(ql[i]-ql[0]-1 + ql[n]-ql[i+1]),MOD)
    res %= MOD
    res += (ql[i]-ql[0])*(ql[n]-ql[i+1])*modpow(3,(ql[i]-ql[0]-1 + ql[n]-ql[i+1]-1),MOD)
    res %= MOD
print(int(res))


Fixed submission:
# -*- coding: utf-8 -*-
import unittest

MOD = 10**9 + 7

def func(s):
    abc = "ABC"
    n = len(s)
    dp =[[0 for _ in range(3+1)] for _ in range(n+1)]
    dp[n][3] = 1

    for i in range(n-1,-1,-1):
        for j in range(3,-1,-1):
            if j==3:
                if s[i]=="?":
                    dp[i][j] = (dp[i+1][j]*3)%MOD
                else:
                    dp[i][j] = dp[i+1][j]
            else:
                m1 = 3 if s[i]=="?" else 1
                m2 = 1 if s[i]=="?" or s[i]==abc[j] else 0
                dp[i][j] = ((m1*dp[i+1][j])%MOD + (m2*dp[i+1][j+1])%MOD)%MOD
    return dp[0][0]

class Test(unittest.TestCase):
    def test(self):
        self.assertEqual(func("A??C"), 8)
        self.assertEqual(func("ABCBC"), 3)
        self.assertEqual(func("????C?????B??????A???????"), 979596887
)

if __name__ == '__main__':
    print(func(input()))

Buggy python submission (verdict: Time Limit Exceeded):
# -*- coding: utf-8 -*-
s = list(input())
n = len(s)
MOD = 10**9 + 7

al = [0]*(n+1)
bl = [0]*(n+1)
cl = [0]*(n+1)
ql = [0]*(n+1)
for i in range(n):
    if s[i]=="A":
        al[i+1] += 1
    elif s[i]=="B":
        bl[i+1] += 1
    elif s[i]=="C":
        cl[i+1] += 1
    else:
        ql[i+1] += 1

    al[i+1] += al[i]
    bl[i+1] += bl[i]
    cl[i+1] += cl[i]
    ql[i+1] += ql[i]

res = 0
for i in range(n):
    if s[i]=="A" or s[i]=="C":
        continue

    res += (al[i]-al[0])*(cl[n]-cl[i+1])*3**(ql[i]-ql[0] + ql[n]-ql[i+1])
    res += (al[i]-al[0])*(ql[n]-ql[i+1])*3**(ql[i]-ql[0] + ql[n]-ql[i+1]-1)
    res += (ql[i]-ql[0])*(cl[n]-cl[i+1])*3**(ql[i]-ql[0]-1 + ql[n]-ql[i+1])
    res += (ql[i]-ql[0])*(ql[n]-ql[i+1])*3**(ql[i]-ql[0]-1 + ql[n]-ql[i+1]-1)
    res %= MOD
print(int(res))


Fixed submission:
# -*- coding: utf-8 -*-
import unittest

MOD = 10**9 + 7

def func(s):
    abc = "ABC"
    n = len(s)
    dp =[[0 for _ in range(3+1)] for _ in range(n+1)]
    dp[n][3] = 1

    for i in range(n-1,-1,-1):
        for j in range(3,-1,-1):
            if j==3:
                if s[i]=="?":
                    dp[i][j] = (dp[i+1][j]*3)%MOD
                else:
                    dp[i][j] = dp[i+1][j]
            else:
                m1 = 3 if s[i]=="?" else 1
                m2 = 1 if s[i]=="?" or s[i]==abc[j] else 0
                dp[i][j] = ((m1*dp[i+1][j])%MOD + (m2*dp[i+1][j+1])%MOD)%MOD
    return dp[0][0]

class Test(unittest.TestCase):
    def test(self):
        self.assertEqual(func("A??C"), 8)
        self.assertEqual(func("ABCBC"), 3)
        self.assertEqual(func("????C?????B??????A???????"), 979596887
)

if __name__ == '__main__':
    print(func(input()))