Fast Walsh Transform

Introduction

The Walsh transform (Walsh Transform)1 is a method widely used in signal processing as an alternative to the discrete Fourier transform in spectral analysis. FFT uses double-precision values, whereas Walsh decomposes a signal into square waves of different oscillation frequencies, so all coefficients are integers with the same absolute value. This avoids floating-point multiplication and improves the computation speed.

Thus, FWT and FFT have the same core idea: transforming an array. Let the result of applying the fast Walsh transform to array AA be FWT[A]FWT[A].

The core idea of FWT is as follows:

We need a new sequence CC, obtained from sequences AA and BB by some operation, namely C=A⋅BC = A \cdot B.

First compute FWT[A],FWT[B]FWT[A], FWT[B] by the forward transform. Then, from FWT[C]=FWT[A]⋅FWT[B]FWT[C]=FWT[A] \cdot FWT[B], compute O(n)O(n) in FWT[C]FWT[C] time, where ⋅\cdot denotes multiplication at corresponding positions of the sequences.

Finally, apply the inverse operation to obtain the original sequence CC. The time complexity is O(nlog⁡n)O(n \log{n}).

In algorithm competitions, FWT is used to solve convolutions whose indices are combined by bitwise operations.

The formula is Ci=∑i=j⊕kAjBkC_{i} = \sum_{i=j \oplus k}A_{j} B_{k}.

Here ⊕\oplus is one of the binary bitwise operations.

We use ∪\cup (bitwise OR), ∩\cap (bitwise AND), and ⊕\oplus (bitwise XOR) as examples.

FWT Operations

OR Convolution

If k=i∪jk=i\cup j, then the positions where the binary digits of ii are 11 and the positions where the binary digits of jj are 11 must form a subset of the positions where the binary digits of kk are 11.

To obtain FWT[C]=FWT[A]⋅FWT[B]FWT[C] = FWT[A] \cdot FWT[B], we must construct the rule for this FWT.

By definition, we can construct FWT[A]i=Ai′=∑i=i∪jAjFWT[A]_i = A'_i = \sum_{i=i\cup j}A_{j} to represent the indices jj whose positions with bit value 11 form a subset of the positions with bit value one in ii.

Therefore:

FWT[A]i⋅FWT[B]i=(∑i∪j=iAj)(∑i∪k=iBk)=∑i∪j=i∑i∪k=iAjBk=∑i∪(j∪k)=iAjBk=FWT[C]i\begin{aligned} FWT[A]_i\cdot FWT[B]_i&=\left(\sum_{i\cup j=i} A_j\right)\left(\sum_{i\cup k=i} B_k\right) \\ &=\sum_{i\cup j=i}\sum_{i\cup k=i}A_jB_k \\ &=\sum_{i\cup(j\cup k)=i}A_jB_k \\ &= FWT[C]_i \end{aligned}

Now let us see how to compute FWT[A]FWT[A].

We clearly cannot enumerate all pairs, which would take O(n2)O(n^2). Since global enumeration is too slow, we use divide and conquer.

Split the whole interval into two halves. After this split, the binary representation of an index follows a regular pattern.

Let A0A_0 denote the first half of AA, and A1A_1 the second half. Then A0A_0 has the highest bit of its largest index equal to 00, so its subsets are just subsets within itself because the highest bit is 00. In contrast, A1A_1 has highest bit 11; its valid subsets include not only itself but also subsets whose highest bit is 00. Therefore,

FWT[A]=merge(FWT[A0],FWT[A0]+FWT[A1])FWT[A] = merge(FWT[A_0], FWT[A_0] + FWT[A_1])

Here merge concatenates the two arrays like strings, ++ is ordinary addition, and it adds corresponding binary positions.

The divide-and-conquer construction completes a merge in O(log⁡n)O(\log{n}) time. Since each merge performs one operation, it obtains O(nlog⁡n)O(n\log{n}) in FWT[A]FWT[A] time.

The inverse is also simple. The subsets of A0A_0 are itself (A0=FWT[A0]A_0 = FWT[A_0]), while the subsets of A1A_1 are FWT[A0]+FWT[A1]FWT[A_0] + FWT[A_1]; hence the inverse recurrence is

UFWT[A′]=merge(UFWT[A0′],UFWT[A1′]−UFWT[A0′])UFWT[A'] = merge(UFWT[A_0'], UFWT[A_1'] - UFWT[A_0'])

Here is the implementation. The forward and inverse transforms can share one function: use type=1\text{type}=1 for the forward transform and type=−1\text{type}=-1 for the inverse transform.

Implementation
void Or(ll *a, ll type) {  // Iterative implementation with a smaller constant factor
  for (ll x = 2; x <= n; x <<= 1) {
    ll k = x >> 1;
    for (ll i = 0; i < n; i += x) {
      for (ll j = 0; j < k; j++) {
        (a[i + j + k] += a[i + j] * type) %= P;
      }
    }
  }
}

AND Convolution

The same reasoning as for OR gives analogous conclusions.

FWT[A]=merge(FWT[A0]+FWT[A1],FWT[A1])FWT[A] = merge(FWT[A_0] + FWT[A_1], FWT[A_1]) UFWT[A′]=merge(UFWT[A0′]−UFWT[A1′],UFWT[A1′])UFWT[A'] = merge(UFWT[A_0'] - UFWT[A_1'], UFWT[A_1'])

Here is the implementation. Use type=1\text{type}=1 for the forward transform and type=−1\text{type}=-1 for the inverse transform.

Implementation
void And(ll *a, ll type) {
  for (ll x = 2; x <= n; x <<= 1) {
    ll k = x >> 1;
    for (ll i = 0; i < n; i += x) {
      for (ll j = 0; j < k; j++) {
        (a[i + j] += a[i + j + k] * type) %= P;
      }
    }
  }
}

XOR Convolution

XOR convolution is based on the following principle.

Let x∘yx\circ y denote the parity of the number of 1s in x∩yx\cap y, namely 11. The definition is x∘y=popcnt(x∩y) mod 2x\circ y=\text{popcnt}(x\cap y)\bmod 2, and it is easy to see that (x∘y)⊕(x∘z)=x∘(y⊕z)(x\circ y)\oplus (x\circ z)=x\circ(y\oplus z).

The operation for FWT[A]FWT[A] follows in the same way.

Set FWT[A]i=∑i∘j=0Aj−∑i∘j=1AjFWT[A]_i=\sum_{i\circ j=0}A_j-\sum_{i\circ j=1}A_j. We prove that FWT[C]=FWT[A]⋅FWT[B]FWT[C] = FWT[A] \cdot FWT[B].

FWT[A]iFWT[B]i=(∑i∘j=0Aj−∑i∘j=1Aj)(∑i∘k=0Bk−∑i∘k=1Bk)=(∑i∘j=0Aj∑i∘k=0Bk+∑i∘j=1Aj∑i∘k=1Bk)−(∑i∘j=0Aj∑i∘k=1Bk+∑i∘j=1Aj∑i∘k=0Bk)=∑(j⊕k)∘i=0AjBk−∑(j⊕k)∘i=1AjBk=FWT[C]i\begin{aligned} FWT[A]_iFWT[B]_i&=\left(\sum_{i\circ j=0}A_j-\sum_{i\circ j=1}A_j\right)\left(\sum_{i\circ k=0}B_k-\sum_{i\circ k=1}B_k\right) \\ &=\left(\sum_{i\circ j=0}A_j\sum_{i\circ k=0}B_k+\sum_{i\circ j=1}A_j\sum_{i\circ k=1}B_k\right)-\left(\sum_{i\circ j=0}A_j\sum_{i\circ k=1}B_k+\sum_{i\circ j=1}A_j\sum_{i\circ k=0}B_k\right) \\ &=\sum_{(j\oplus k)\circ i=0}A_jB_k-\sum_{(j\oplus k)\circ i=1}A_jB_k \\ &=FWT[C]_i \end{aligned}

Let us see how to compute the values of A,BA,B quickly; again, use divide and conquer.

For the subsequence FWT[A0]FWT[A_0] whose current bit of ii is 00, the ∘\circ operation gives the same result when combined with 00 or 11, because 0∩0=0,0∩1=00\cap 0=0,0\cap1=0. Thus, in FWT[A]=∑i∘j=0Aj−∑i∘j=1AjFWT[A]=\sum_{i\circ j=0}A_j-\sum_{i\circ j=1}A_j, the term ∑i∘j=1Aj=0\sum_{i\circ j=1}A_j=0 is zero.

For the subsequence A1A_1 whose current bit of ii is 11, the ∘\circ operation gives 00 when combined with 00, and 11 when combined with 11, because 1∩0=0,1∩1=11\cap 0=0,1\cap1=1.

Combining these observations gives:

FWT[A]=merge((FWT[A0]+FWT[A1])−0,FWT[A0]−FWT[A1])FWT[A]=merge((FWT[A_0]+FWT[A_1])-0, FWT[A_0]-FWT[A_1])

That is:

FWT[A]=merge(FWT[A0]+FWT[A1],FWT[A0]−FWT[A1])FWT[A] = merge(FWT[A_0] + FWT[A_1], FWT[A_0] - FWT[A_1])

The inverse transform follows immediately:

UFWT[A′]=merge(UFWT[A0′]+UFWT[A1′]2,UFWT[A0′]−UFWT[A1′]2)UFWT[A'] = merge(\frac{UFWT[A_0'] + UFWT[A_1']}{2}, \frac{UFWT[A_0'] - UFWT[A_1']}{2})

The code is given below. Use type=1\text{type}=1 for the forward transform and type=12\text{type}=\frac{1}{2} for the inverse transform.

Implementation
void Xor(ll *a, ll type) {
  for (ll x = 2; x <= n; x <<= 1) {
    ll k = x >> 1;
    for (ll i = 0; i < n; i += x) {
      for (ll j = 0; j < k; j++) {
        (a[i + j] += a[i + j + k]) %= P;
        (a[i + j + k] = a[i + j] - a[i + j + k] * 2) %= P;
        (a[i + j] *= type) %= P;
        (a[i + j + k] *= type) %= P;
      }
    }
  }
}

XNOR Convolution

By analogy with XOR, we obtain the formula:

FWT[A]i=∑C1Aj−∑C2AjFWT[A]_{i} = \sum_{C_1}A_{j} - \sum_{C_2}A_{j} (C1C_1 denotes the indices for which popcnt(x∪y) mod 2\text{popcnt}(x\cup y)\bmod 2 is 00, while C2C_2 denotes the indices for which popcnt(x∪y) mod 2\text{popcnt}(x\cup y)\bmod 2 is 11).

FWT[A]=merge(FWT[A1]−FWT[A0],FWT[A1]+FWT[A0])FWT[A] = merge(FWT[A_1] - FWT[A_0], FWT[A_1] + FWT[A_0]) UFWT[A′]=merge(UFWT[A1′]−UFWT[A0′]2,UFWT[A1′]+UFWT[A0′]2)UFWT[A'] = merge(\frac{UFWT[A_1'] - UFWT[A_0']}{2}, \frac{UFWT[A_1'] + UFWT[A_0']}{2})

Another View of FWT

Let c(i,j)c(i,j) be the contribution coefficient of AjA_j to FWT[A]iFWT[A]_i. We can describe the FWT process as follows:

FWT[A]i=∑j=0n−1c(i,j)AjFWT[A]_i = \sum_{j=0}^{n-1} c(i,j) A_j

Since:

FWT[A]i⋅FWT[B]i=FWT[C]iFWT[A]_i\cdot FWT[B]_i=FWT[C]_i

A direct proof gives c(i,j)c(i,k)=c(i,j⊙k)c(i,j)c(i,k)=c(i,j\odot k), where ⊙\odot is any bitwise operation.

The function cc also has an important property: it can be processed bit by bit.

For example, during the transform we have:

FWT[A]i=∑j=0n−1c(i,j)AjFWT[A]_i = \sum_{j=0}^{n-1} c(i,j) A_j

This direct expression is inefficient, so split it as follows:

FWT[A]i=∑j=0n/2−1c(i,j)Aj+∑j=n/2n−1c(i,j)AjFWT[A]_i = \sum_{j=0}^{n/2-1} c(i,j) A_j+\sum_{j=n/2}^{n-1} c(i,j) A_j

Comparing the preceding and following expressions, the only difference in i,ji,j is the highest bit.

Remove the highest bit of i,ji,j and call the result i′,j′i',j'; let i0i_0 be the highest bit of ii. Then:

FWT[A]i=c(i0,0)∑j=0n/2−1c(i′,j′)Aj+c(i0,1)∑j=n/2n−1c(i′,j′)AjFWT[A]_i = c(i_0,0)\sum_{j=0}^{n/2-1} c(i',j') A_j+c(i_0,1)\sum_{j=n/2}^{n-1} c(i',j') A_j

If i0=0i_0=0, then:

FWT[A]i=c(0,0)∑j=0n/2−1c(i′,j′)Aj+c(0,1)∑j=n/2n−1c(i′,j′)AjFWT[A]_i = c(0,0)\sum_{j=0}^{n/2-1} c(i',j') A_j+c(0,1)\sum_{j=n/2}^{n-1} c(i',j') A_j

If i0=1i_0=1, then:

FWT[A]i=c(1,0)∑j=0n/2−1c(i′,j′)Aj+c(1,1)∑j=n/2n−1c(i′,j′)AjFWT[A]_i = c(1,0)\sum_{j=0}^{n/2-1} c(i',j') A_j+c(1,1)\sum_{j=n/2}^{n-1} c(i',j') A_j

In other words, we only need:

[c(0,0)c(0,1)c(1,0)c(1,1)]\begin{bmatrix} c(0,0) & c(0,1) \\ c(1,0) & c(1,1) \end{bmatrix}

These four numbers suffice to complete the transform. We call this matrix the bit matrix.

For the inverse transform, we need the inverse of the bit matrix above.

If the inverse matrix is c−1c^{-1}, a similar argument gives the original values:

Ai=∑j=0nc−1(i,j)FWT[A]jA_i = \sum_{j=0}^n c^{-1}(i,j) FWT[A]_j

The inverse matrix does not always exist. For example, if there is a row 00 or a column 00, the matrix has no inverse, so the construction requires care.

Bitwise OR

We can construct the matrix

[1011]\begin{bmatrix} 1 & 0 \\ 1 & 1 \end{bmatrix}

It satisfies c(i,j)c(i,k)=c(i,j∪k)c(i,j)c(i,k)=c(i,j\cup k). This is exactly the same as the previously derived FWT[A]=merge(FWT[A0],FWT[A0]+FWT[A1])FWT[A]=\text{merge}(FWT[A_0], FWT[A_0]+FWT[A_1]). Similarly, the following matrix also satisfies the condition, but we generally use the first one:

[1110]\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}

Although the following matrix also satisfies c(i,j)c(i,k)=c(i,j∪k)c(i,j)c(i,k)=c(i,j\cup k), it contains a row 00, has no inverse, and is therefore invalid:

[0011]\begin{bmatrix} 0 & 0 \\ 1 & 1 \end{bmatrix}

For the inverse transform, invert the matrix. For the top matrix, the result is:

[10−11]\begin{bmatrix} 1 & 0 \\ -1 & 1 \end{bmatrix}

Then substitute this inverse matrix into the forward-transform procedure.

Bitwise AND

We can construct the matrix

[1101]\begin{bmatrix} 1 & 1 \\ 0 & 1 \end{bmatrix}

It satisfies c(i,j)c(i,k)=c(i,j∩k)c(i,j)c(i,k)=c(i,j\cap k).

The inverse matrix is:

[1−101]\begin{bmatrix} 1 & -1 \\ 0 & 1 \end{bmatrix}

Bitwise XOR

We can construct the matrix

[111−1]\begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix}

It satisfies c(i,j)c(i,k)=c(i,j⊕k)c(i,j)c(i,k)=c(i,j\oplus k).

The inverse matrix is:

[0.50.50.5−0.5]\begin{bmatrix} 0.5 & 0.5 \\ 0.5 & -0.5 \end{bmatrix}

FWT Is a Linear Transform

FWT is a linear transform. In other words, it satisfies:

FWT[A+B]=FWT[A]+FWT[B]FWT[A+B]=FWT[A]+FWT[B]

and:

FWT[c⋅A]=c⋅FWT[A]FWT[c\cdot A]=c\cdot FWT[A]

K-Dimensional FWT

At its core, a bitwise operation acts on an nn-dimensional {0,1}\{0,1\} vector. OR takes the max⁡\max in each dimension, AND takes the min⁡\min, and XOR adds corresponding coordinates modulo  mod 2\bmod 2.

A key feature of bitwise operations is that the coordinates of the vector are independent.

Extend {0,1}\{0,1\} to [0,K)∩Z[0,K)\cap \mathbf{Z}, that is, to base-KK, and see what happens.

Max Operation

Extend the ∪\cup operation to base-KK. Define i∪ji\cup j to take the max⁡\max in each digit; then

c(i,j)c(i,k)=c(i,j∪k)c(i,j)c(i,k)=c(i,j\cup k)

If j=kj=k, the equation becomes:

c(i,j)c(i,j)=c(i,j)c(i,j)c(i,j)=c(i,j)

Thus, in every row, the 11s must occur before the 00s; placing them afterward is invalid. One valid construction is:

[1000110011101111]\begin{bmatrix} 1 & 0 & 0 & 0 \\ 1 & 1 & 0 & 0 \\ 1 & 1 & 1 & 0 \\ 1 & 1 & 1 & 1 \end{bmatrix}

Its inverse is:

[1000−11000−11000−11]\begin{bmatrix} 1 & 0 & 0 & 0 \\ -1 & 1 & 0 & 0 \\ 0 & -1 & 1 & 0 \\ 0 & 0 & -1 & 1 \end{bmatrix}

Min Operation

Extend the ∩\cap operation to base-KK. Define i∩ji\cap j to take the min⁡\min in each digit; then

c(i,j)c(i,k)=c(i,j∩k)c(i,j)c(i,k)=c(i,j\cap k)

If j=kj=k, the equation again becomes:

c(i,j)c(i,j)=c(i,j)c(i,j)c(i,j)=c(i,j)

Thus, in every row, the 11s must occur after the 00s; placing them beforehand is invalid. One valid construction is:

[1111011100110001]\begin{bmatrix} 1 & 1 & 1 & 1 \\ 0 & 1 & 1 & 1 \\ 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 1 \end{bmatrix}

Its inverse is:

[1−10001−10001−10001]\begin{bmatrix} 1 & -1 & 0 & 0 \\ 0 & 1 & -1 & 0 \\ 0 & 0 & 1 & -1 \\ 0 & 0 & 0 & 1 \end{bmatrix}

The first two operations are used less often. The more common one is:

Carryless Addition

Extend the ⊕\oplus operation to base-KK. Define i⊕ji\oplus j as digitwise addition modulo  mod K\bmod K; then

c(i,j)c(i,k)=c(i,j⊕k)c(i,j)c(i,k)=c(i,j\oplus k)

Choosing c(i,j)=ωKjc(i,j)=\omega_{K}^j satisfies the requirement:

ωKjωKk=ωKj⊕k\omega_{K}^j\omega_{K}^k=\omega_{K}^{j\oplus k}

However, identical rows give a singular matrix, so instead choose c(i,j)=ωK(i−1)jc(i,j)=\omega_{K}^{(i-1)j}.

This gives the following matrix:

[111⋯11ωK1ωK2⋯ωKk−11ωK2ωK4⋯ωK2(k−1)1ωK3ωK6⋯ωK3(k−1)⋮⋮⋮⋱⋮1ωKk−1ωK2(k−1)⋯ωK(k−1)(k−1)]\begin{bmatrix} 1 & 1 & 1 & \cdots & 1 \\ 1 & \omega_{K}^1 & \omega_{K}^2 & \cdots & \omega_{K}^{k-1} \\ 1 & \omega_{K}^2 & \omega_{K}^4 & \cdots & \omega_{K}^{2(k-1)} \\ 1 & \omega_{K}^3 & \omega_{K}^6 & \cdots & \omega_{K}^{3(k-1)} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & \omega_{K}^{k-1} & \omega_{K}^{2(k-1)} & \cdots & \omega_{K}^{(k-1)(k-1)} \end{bmatrix}

This is a Vandermonde matrix; its inverse is:

1K[111⋯11ωK−1ωK−2⋯ωK−(k−1)1ωK−2ωK−4⋯ωK−2(k−1)1ωK−3ωK−6⋯ωK−3(k−1)⋮⋮⋮⋱⋮1ωK−(k−1)ωK−2(k−1)⋯ωK−(k−1)(k−1)]\frac{1}{K}\begin{bmatrix} 1 & 1 & 1 & \cdots & 1 \\ 1 & \omega_{K}^{-1} & \omega_{K}^{-2} & \cdots & \omega_{K}^{-(k-1)} \\ 1 & \omega_{K}^{-2} & \omega_{K}^{-4} & \cdots & \omega_{K}^{-2(k-1)} \\ 1 & \omega_{K}^{-3} & \omega_{K}^{-6} & \cdots & \omega_{K}^{-3(k-1)} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & \omega_{K}^{-(k-1)} & \omega_{K}^{-2(k-1)} & \cdots & \omega_{K}^{-(k-1)(k-1)} \end{bmatrix}

If the modulus in the problem contains a suitable root of unity, the transform is straightforward to implement.

However, a root of unity may not exist modulo the given modulus. Consider an extension field: define xx with xK=1x^K=1, and substitute xx into the computation. Every value then becomes a polynomial in xx of degree k−1k-1. We only need to compute modulo  mod xK−1\bmod {x^K-1}. The matrix can therefore be written as:

[111⋯11x1x2⋯xk−11x2x4⋯x2(k−1)1x3x6⋯x3(k−1)⋮⋮⋮⋱⋮1xk−1x2(k−1)⋯x(k−1)(k−1)]\begin{bmatrix} 1 & 1 & 1 & \cdots & 1 \\ 1 & x^1 & x^2 & \cdots & x^{k-1} \\ 1 & x^2 & x^4 & \cdots & x^{2(k-1)} \\ 1 & x^3 & x^6 & \cdots & x^{3(k-1)} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & x^{k-1} & x^{2(k-1)} & \cdots & x^{(k-1)(k-1)} \end{bmatrix}

This may introduce zero divisors, meaning one value has multiple representations, so its actual value is ambiguous.

Instead of reducing  mod xK−1\bmod {x^K-1}, take  mod \bmod modulo the cyclotomic polynomial ΦK(x)\Phi_{K}(x). It makes xx have order kk and is irreducible over Q\mathbb{Q}, so the above computation can be performed modulo  mod ΦK(x)\bmod {\Phi_{K}(x)}.

One issue is that the constants in  mod ΦK(x)\bmod \Phi_{K}(x) are large because Φ\Phi itself is a polynomial. Since ΦK(x)∣xk−1\Phi_{K}(x)\mid x^k-1, we can reduce modulo  mod xk−1\bmod x^k -1 during the computation and reduce modulo  mod ΦK(x)\bmod \Phi_{K}(x) only at the end.

Examples

"CF 1103E" Radix sum

Given a sequence a1,a2,...,ana_1,a_2,...,a_n of length nn, for every p∈[0,n−1]p \in [0,n-1], find the number of integer sequences i1,i2,...,ini_1,i_2,...,i_n satisfying the following conditions, modulo 2582^{58}:

  • ∀j∈[1,n],ij∈[1,n]\forall j \in [1,n] , i_j \in [1,n];
  • ∑j=1naij=p\sum\limits_{j=1}^n a_{i_j} = p, where addition is defined as decimal carryless addition.

n≤105,ai≤105n\le10^5,a_i\le10^5

Solution. We can use DP: let fi,sf_{i,s} denote the state after considering the ii-th number, with current carryless-addition state ss. Since FWT is linear, transform the sequence into its FWT point-value representation, raise it to the nn-th power, and transform it back.

The idea above is routine, but the modulus is 2582^{58}, which has no root of unity. We therefore use an extension field. The cyclotomic polynomial here is Φ10(x)=x4−x3+x2−x+1\Phi_{10}(x)=x^4-x^3+x^2-x+1.

During UFWT we need to divide by 1010, but {14} has no inverse modulo 1010. In contrast, 2582^{58} has an inverse modulo 55, namely 2582^{58}. We only need to divide by another 5764607523034234957646075230342349. Let the answer after division by 22 be 55, and let the true answer be xx; then yy. Consequently 25y≡x(mod264)2^5y\equiv x\pmod{2^{64}}, so y≡x25(mod264−5)y\equiv \frac{x}{2^5}\pmod{2^{64-5}}. Hence the final answer can simply be divided by y≡x25(mod259)y\equiv \frac{x}{2^5}\pmod{2^{59}}. Although the reason for using modulus 252^5 is unclear, reducing once more gives the desired result.

The constraint is 2582^{58}.

[CF103329F] [XXII Opencup, Grand Prix of XiAn] The Struggle

Given an elliptic curve EE, all of whose integral-point coordinates lie in [1,4⋅106][1,4 \cdot 10^6], compute ∑(x,y)∈E(x⊕y)33x−2y−1mod  109+7\sum_{(x,y) \in E} (x \oplus y)^{33}x^{-2}y^{-1} \mod 10^9+7.

Solution

This problem is not a direct application; the author provides a detailed English solution at this link.

References

Footnotes

  1. Wikipedia ↩

This content comes from OI Wiki: Fast Walsh Transform. See the original for authors and revision history. AIOJ has adapted the formatting, in-site links, and resource paths.

Content is shared under CC BY-SA 4.0 and SATA license; additional terms are governed by the original notice. Thanks to the OI Wiki authors and contributors; per the SATA terms, please visit the OI Wiki repository and star it to show your support.