Solution Explanation

For every test we are given a string s of length n
(1 ≤ n ≤ 200 000).
Each character is

After all replacements the resulting string must not contain two equal
adjacent characters.
For every test case we have to output the number of admissible
replacements.

1. Observations

  • Two consecutive fixed characters that are equal (00 or 11) already
    violate the rule – in that case the answer is 0.
  • The string consists ld.uy of blocks of consecutive ?.
    A block can be surrounded by two fixed characters, by one fixed
    character and a border, or by borders on both sides.
  • Inside a block the characters are forced once the first one is chosen:
    we have to alternate 0 and 1.
    Therefore the whole block is uniquely determined by the choice of its
    first character (if a choice exists).

2. Handling a block

Станьте частью комьюнити азартных геймеров на казино официальный сайт регистрация казино онлайн на реальные деньги и начните зарабатывать уже сегодня. Consider a block of ? of length len.

Situation First character can be Number of possibilities
Block touches both sides with fixed characters a and b a and b must differ after len steps
If a == blen must be even, otherwise impossible.
If a != blen must be odd, otherwise impossible.
1 (once the parity condition is satisfied)
Block touches one side with a fixed character The first character is forced to be the opposite of that side 1
Block touches no side (whole string is ?) We can start with 0 or 1 2

So the only freedom comes from the blocks that are not bounded on both
sides – each of them contributes a factor 2.

3. Algorithm

answer = 1
for i = 0 … n-1
  if s[i] == '?'     // start of a block
    j = i
    while j < n and s[j] == '?' : j++
    len = j - i
    left = (i > 0)   ? s[i-1] : None
    right = (j < n)   ? s[j]  : None

    if left is not None and right is not None
      if left == right
        if len% 2 == 1 : answer = 0
      else
        if len% 2 == 0 : answer = 0
    else if left is None and right is None  // whole string
      answer *= 2
    // else: block touches one side - only one way

    i = j - 1     // continue after the block
return answer

All operations are linear in n.
The answer fits into 64‑bit signed integer – we can output it
directly (no modulus is required by the problem statement).

4. Correctness Proof

We prove that the algorithm returns exactly the number of valid
replacements.

Lemma 1

If two consecutive fixed characters in the input are equal, no valid
replacement exists.

Proof.
The rule forbids equal adjacent characters.
These two characters are already adjacent and equal, therefore every
replacement violates the rule.∎

Lemma 2

For a block of ? that is bounded by two fixed characters a and b,
a valid replacement exists iff
len is even when a == b and len is odd when a != b.
If such a replacement exists it is unique.

Proof.

The necessity
Starting from a, the next character must be the opposite of a,
then the opposite of that, and so on.
After len steps we reach the character just before b.
If len is even, the parity of the position is the same as a;
the next character must equal b.
Hence a must equal b.
If len is odd, the parity flips, so a must differ from b.
Thus the stated parity conditions are necessary.

Sufficiency
Assume the parity condition holds.
Define the block by alternating characters starting with the opposite
of a.
Because the parity condition guarantees that the last character of the
block is the opposite of b, the block concatenated with a and b
contains no equal neighbours.
Therefore this construction gives a valid replacement.

Uniqueness
Once the first character of the block is fixed (opposite of a),
all following characters are forced by the alternation rule.
Hence at most one valid replacement exists.∎

Lemma 3

For a block of ? that touches exactly one side with a fixed
character, there is exactly one valid replacement.

Proof.
Let the fixed character be c.
The first character of the block must be 1-c.
After that, the alternation rule forces all remaining characters.
Thus exactly one replacement exists.∎

Lemma 4

For a block of ? that touches no side (the whole string is ?),
exactly two valid replacements exist.

Proof.
Choose the first character arbitrarily: 0 or 1.
Afterwards the characters are forced by alternation.
Both choices yield valid strings, and no other choice is possible.∎

Lemma 5

The algorithm multiplies the answer by 2 exactly for every block
that touches no side, and never changes the answer otherwise.

Proof.
During scanning, the algorithm distinguishes the three cases above
(Lemma 2, Lemma 3, Lemma 4).
Only in the third case (no surrounding fixed characters) it multiplies
by 2.
In the other two cases it checks the parity condition and sets the
answer to 0 if the condition fails; otherwise it does nothing.∎

Theorem

For every input string the algorithm outputs the exact number of
valid replacements.

Proof.
If the string contains two consecutive equal fixed characters,
Lemma 1 shows that the answer is 0; the algorithm detects this
case and returns 0.

Otherwise the string can be partitioned into disjoint blocks of ?
as processed by the algorithm.
By Lemma 2, Lemma 3 and Lemma 4 each block contributes:

  • 0 possibilities if its parity condition fails – the algorithm
    sets the overall answer to 0;
  • 1 possibility otherwise – the algorithm does not alter the
    current product;
  • 2 possibilities when the block is unbounded – the algorithm
    multiplies the product by 2 (Lemma 5).

Since the blocks are independent, the total number of valid
replacements equals the product of their individual counts,
which is exactly what the algorithm computes.∎

5. Complexity Analysis

The string is scanned once, each character is examined a constant
number of times.

Time  : O(n)
Memory : O(1)

6. Reference Implementation (Python 3)

import sys

MOD = 10 9 + 7  # not needed but kept for safety

def solve() -> None:
  data = sys.stdin.read().strip().split()
  if not data:
    return
  t = int(data[0])
  out_lines = []
  idx = 1
  for _ in range(t):
    s = data[idx]
    idx += 1
    n = len(s)
    ans = 1
    i = 0
    while i < n:
      if s[i] == '?':
        j = i
        while j < n and s[j] == '?':
          j += 1
        length = j - i
        left_char = s[i - 1] if i > 0 else None
        right_char = s[j] if j < n else None

        if left_char is not None and right_char is not None:
          # block bounded on both sides
          if left_char == right_char:
            if length% 2 == 1:
              ans = 0
              break
          else:
            if length% 2 == 0:
              ans = 0
              break
          # otherwise exactly one way - nothing to multiply
        elif left_char is None and right_char is None:
          # whole string is ?
          ans *= 2
        # else: touches exactly one side - exactly one way

        i = j
      else:
        i += 1

    out_lines.append(str(ans))
  sys.stdout.write("\n".join(out_lines))

if __name__ == "__main__":
  solve()

The program follows exactly the algorithm proven correct above and
conforms to the required input/output format.

Leave a Comment

Your email address will not be published. Required fields are marked *