import numpy as np NN = np.uint64(1e9 + 7) def quick_pascal_sum(n): NNN = NN qp = np.zeros((n, 3), dtype=np.uint64) qp[0, 0] = 1 for row in range(1, n): qp[row, 0] = (qp[row-1, 0] + qp[row-1,-1]) % NNN qp[row, 1] = (qp[row-1, 1] + qp[row-1, 0]) % NNN qp[row, 2] = (qp[row-1, 2] + qp[row-1, 1]) % NNN return qp def quick_check(c, z): return c % 3 != z % 3 def swap(s): if s == b'c'[0]: return b'z'[0] if s == b'z'[0]: return b'c'[0] raise ValueError def can_be_interleaving(s, start_letter): next_letter = start_letter for c in s: if c == b'n'[0]: next_letter = swap(next_letter) continue if c == next_letter: next_letter = swap(next_letter) else: return False return True C = ord('c') Z = ord('z') N = ord('n') def check_me(n, c, z, even, odd): global qp TOTAL = np.int64(0) for k in range(3): if quick_check(c+k, z+n-k): # print(k, qp[n, k]) TOTAL += qp[n, k] TOTAL %= NN n_letters = n+c+z if n_letters % 2 == 1: half = n_letters // 2 # CZCZCZC # CNNNNNC oddC = odd[C] + odd[N] evenC = even[C] + even[N] oddZ = odd[Z] + odd[N] evenZ = even[Z] + even[N] if oddC == half + 1 and evenZ == half: TOTAL += NN - 1 TOTAL %= NN if oddZ == half + 1 and evenC == half: TOTAL += NN - 1 TOTAL %= NN return int(TOTAL) NUM, Q = list(map(int, input().strip().split(' '))) S = bytearray(input().strip().lower(), 'ascii') qp = quick_pascal_sum(NUM+1) from collections import defaultdict odd = { N: 0, C: 0, Z: 0 } even = { N: 0, C: 0, Z: 0 } for i, c in enumerate(S): if (i+1) % 2 == 0: even[c] += 1 else: odd[c] += 1 counters = { N : S.count(b'n'), C : S.count(b'c'), Z : S.count(b'z') } print(check_me(counters[N], counters[C], counters[Z], even, odd)) for q in range(Q): line = input().strip().split(' ') idx = int(line[0]) letter = bytearray(line[1].lower(), 'ascii')[0] # old_letter = S[idx-1] S[idx-1] = letter if idx % 2 == 0: even[old_letter] -= 1 even[letter] += 1 else: odd[old_letter] -= 1 odd[letter] += 1 counters[old_letter] -= 1 counters[letter] += 1 print(check_me(counters[N], counters[C], counters[Z], even, odd))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | import numpy as np NN = np.uint64(1e9 + 7) def quick_pascal_sum(n): NNN = NN qp = np.zeros((n, 3), dtype=np.uint64) qp[0, 0] = 1 for row in range(1, n): qp[row, 0] = (qp[row-1, 0] + qp[row-1,-1]) % NNN qp[row, 1] = (qp[row-1, 1] + qp[row-1, 0]) % NNN qp[row, 2] = (qp[row-1, 2] + qp[row-1, 1]) % NNN return qp def quick_check(c, z): return c % 3 != z % 3 def swap(s): if s == b'c'[0]: return b'z'[0] if s == b'z'[0]: return b'c'[0] raise ValueError def can_be_interleaving(s, start_letter): next_letter = start_letter for c in s: if c == b'n'[0]: next_letter = swap(next_letter) continue if c == next_letter: next_letter = swap(next_letter) else: return False return True C = ord('c') Z = ord('z') N = ord('n') def check_me(n, c, z, even, odd): global qp TOTAL = np.int64(0) for k in range(3): if quick_check(c+k, z+n-k): # print(k, qp[n, k]) TOTAL += qp[n, k] TOTAL %= NN n_letters = n+c+z if n_letters % 2 == 1: half = n_letters // 2 # CZCZCZC # CNNNNNC oddC = odd[C] + odd[N] evenC = even[C] + even[N] oddZ = odd[Z] + odd[N] evenZ = even[Z] + even[N] if oddC == half + 1 and evenZ == half: TOTAL += NN - 1 TOTAL %= NN if oddZ == half + 1 and evenC == half: TOTAL += NN - 1 TOTAL %= NN return int(TOTAL) NUM, Q = list(map(int, input().strip().split(' '))) S = bytearray(input().strip().lower(), 'ascii') qp = quick_pascal_sum(NUM+1) from collections import defaultdict odd = { N: 0, C: 0, Z: 0 } even = { N: 0, C: 0, Z: 0 } for i, c in enumerate(S): if (i+1) % 2 == 0: even[c] += 1 else: odd[c] += 1 counters = { N : S.count(b'n'), C : S.count(b'c'), Z : S.count(b'z') } print(check_me(counters[N], counters[C], counters[Z], even, odd)) for q in range(Q): line = input().strip().split(' ') idx = int(line[0]) letter = bytearray(line[1].lower(), 'ascii')[0] # old_letter = S[idx-1] S[idx-1] = letter if idx % 2 == 0: even[old_letter] -= 1 even[letter] += 1 else: odd[old_letter] -= 1 odd[letter] += 1 counters[old_letter] -= 1 counters[letter] += 1 print(check_me(counters[N], counters[C], counters[Z], even, odd)) |