B2: The Hidden Polynomial I

Time Limit: 3 seconds

Memory Limit: 512 MiB

Score: 600 points

Problem Statement

Story

We are the QCoder Order, worshippers of quantum programming. We have a hidden polynomial, f(x)f(x), that has been protected for centuries. The polynomial f(x)f(x) is defined using an nn-bit odd integer AA and an nn-bit integer BB as follows:

f(x)=Ax2+Ax+Bf(x) = Ax^2 + Ax + B

Recently, we performed a sacred ritual to transfer this polynomial to an oracle OO. If the ritual was successful, the oracle OO should behave as follows:

∣x⟩∣y⟩→O∣x⟩∣y⊕(f(x) mod 2n)⟩\ket{x}\ket{y} \xrightarrow{O} \ket{x}\ket{y \oplus (f(x)\bmod 2^n)}

Here, ⊕\oplus denotes the bitwise XOR operator, and (f(x) mod 2n)(f(x)\bmod 2^n) denotes the remainder when f(x)f(x) is divided by 2n2^n.

Unfortunately, because the ritual's procedure is extremely complicated, no one knows if the oracle was generated correctly. We know that if the ritual failed, the coefficient AA would be recorded as 00.

Your mission is to determine whether the ritual succeeded—i.e., whether the oracle OO has been implemented correctly.

Note that the polynomial f(x)f(x) is our top secret. To protect the details of f(x)f(x), you can only call the oracle 11 time.

Detailed Description

Given an integer nn, you may implement any operations you like on a 2n2n-qubit quantum circuit qcbefore\mathrm{qc}_{\mathrm{before}}, and on a quantum circuit qcafter\mathrm{qc}_{\mathrm{after}} that has 2n2n qubits and 11 classical register.

Implement operations on these quantum circuits that satisfy the following requirement.

The given oracle OO is either O1O_1 or O0O_0. For any pair of integers (x,y)(x,y) satisfying 0≤x<2n0 \leq x < 2^n and 0≤y<2n0 \leq y < 2^n, the required transformation is as follows:

∣x⟩∣y⟩→O1∣x⟩∣y⊕(f(x) mod 2n)⟩\ket{x}\ket{y} \xrightarrow{O_1} \ket{x}\ket{y \oplus (f(x)\bmod 2^n)} ∣x⟩∣y⟩→O0∣x⟩∣y⊕(B mod 2n)⟩\ket{x}\ket{y} \xrightarrow{O_0} \ket{x}\ket{y \oplus (B\bmod 2^n)}

When qcbefore, O, qcafter\mathrm{qc}_{\mathrm{before}},\,O,\,\mathrm{qc}_{\mathrm{after}} are applied in this order to the zero state ∣0⟩\ket{0}, the measurement result written to the classical register must be 11 if O=O1O=O_1, and 00 if O=O0O=O_0.

Constraints

  • n>2n > 2
  • 0≤A,B<2n0 \leq A, B < 2^n
  • AA is odd.
  • Integers must be encoded by little-endian.
  • Global phase is ignored in judge.
  • The submitted code must follow the specified format:
    • before_oracle(n: int) -> QuantumCircuit: the quantum circuit qcbefore\mathrm{qc}_{\mathrm{before}} before calling the oracle.
    • after_oracle(n: int) -> QuantumCircuit: the quantum circuit qcafter\mathrm{qc}_{\mathrm{after}} after calling the oracle. You must write the measurement result to the classical register c in this quantum circuit.
from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister
 
"""
You can apply measurement as follows
         (e.g., when measuring x[0]):
qc.measure(x[0], c[0])
"""
 
 
def before_oracle(n: int) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(n)
    qc = QuantumCircuit(x, y)
 
    # Write your code here:
 
    return qc
 
 
def after_oracle(n: int) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(n)
    c = ClassicalRegister(1)
    qc = QuantumCircuit(x, y, c)
 
    # Write your code here:
 
    return qc

In the judge, the functions are called in the following order:

  1. before_oracle(n)
  2. (the oracle OO)
  3. after_oracle(n)

After that, the judge concludes that “the ritual succeeded” if c=1c = 1, and that “the ritual failed” if c=0c = 0.

Hints

Open
  • You can use the following code to test your solution in your local environment.
    • Note that you need to define before_oracle, oracle, and after_oracle in advance.
from qiskit_aer import AerSimulator
from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister, transpile
 
# Define or import before_oracle, oracle, and after_oracle here.
 
# Sample input
n: int = 3
A: int = 1  # A is odd
B: int = 4
 
# Build the quantum circuit.
x = QuantumRegister(n)
y = QuantumRegister(n)
c = ClassicalRegister(1)
main_qc = QuantumCircuit(x, y, c)
main_qc.compose(before_oracle(n), inplace=True)
main_qc.compose(oracle(), inplace=True)
main_qc.compose(after_oracle(n), inplace=True)
 
# Simulate the quantum circuit and retrieve the contents of register c.
simulator = AerSimulator()
job = simulator.run(
    transpile(main_qc, simulator),
    shots=1024,
)
counts: dict[str, int] = job.result().get_counts()
print(f"Measurement counts: {counts}")

Please sign in to submit your answer.