Program to generate an array having convolution of two given arrays
Last Updated :
28 Apr, 2024
Given two arrays A[] and B[] consisting of N and M integers respectively, the task is to construct a convolution array C[] of size (N + M - 1).
The convolution of 2 arrays is defined as C[i + j] = ?(a[i] * b[j]) for every i and j.
Note: If the value for any index becomes very large, then print it to modulo 998244353.
Examples:
Input: A[] = {1, 2, 3, 4}, B[] = {5, 6, 7, 8, 9}
Output: {5, 16, 34, 60, 70, 70, 59, 36}
Explanation:
Size of array, C[] = N + M - 1 = 8.
C[0] = A[0] * B[0] = 1 * 5 = 5
C[1] = A[0] * B[1] + A[1] * B[0] = 1 * 6 + 2 * 5 = 16
C[2] = A[0] * B[2] + A[1] * B[1] + A[2] * B[0] = 1 * 7 + 2 * 6 + 3 * 5 = 34
Similarly, C[3] = 60, C[4] = 70, C[5] = 70, C[6] = 59, C[7] = 36.
Input: A[] = {10000000}, B[] = {10000000}
Output: {871938225}
Explanation:
Size of array, C[] = N + M - 1 = 1.
C[0] = A[0] * B[0] = (10000000 * 10000000) % 998244353 = 871938225
Naive Approach: In the convolution array, each term C[i + j] = (a[i] * b[j]) % 998244353. Therefore, the simplest approach is to iterate over both the arrays A[] and B[] using two nested loops to find the resulting convoluted array C[].
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
constexpr int MOD = 998244353;
// Function to generate a convolution
// array of two given arrays
void findConvolution(const vector<int>& a,
const vector<int>& b)
{
// Stores the size of arrays
int n = a.size(), m = b.size();
// Stores the final array
vector<long long> c(n + m - 1);
// Traverse the two given arrays
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
// Update the convolution array
c[i + j] += 1LL*(a[i] * b[j]) % MOD;
}
}
// Print the convolution array c[]
for (int k = 0; k < c.size(); ++k) {
c[k] %= MOD;
cout << c[k] << " ";
}
}
// Driver Code
int main()
{
vector<int> A = { 1, 2, 3, 4 };
vector<int> B = { 5, 6, 7, 8, 9 };
findConvolution(A, B);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
static int MOD = 998244353;
// Function to generate a convolution
// array of two given arrays
static void findConvolution(int[] a,
int[] b)
{
// Stores the size of arrays
int n = a.length, m = b.length;
// Stores the final array
int[] c = new int[(n + m - 1)];
// Traverse the two given arrays
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < m; ++j)
{
// Update the convolution array
c[i + j] += (a[i] * b[j]) % MOD;
}
}
// Print the convolution array c[]
for(int k = 0; k < c.length; ++k)
{
c[k] %= MOD;
System.out.print(c[k] + " ");
}
}
// Driver Code
public static void main(String args[])
{
int[] A = { 1, 2, 3, 4 };
int[] B = { 5, 6, 7, 8, 9 };
findConvolution(A, B);}
}
// This code is contributed by souravghosh0416
Python3
# Python3 program for the above approach
MOD = 998244353
# Function to generate a convolution
# array of two given arrays
def findConvolution(a, b):
global MOD
# Stores the size of arrays
n, m = len(a), len(b)
# Stores the final array
c = [0] * (n + m - 1)
# Traverse the two given arrays
for i in range(n):
for j in range(m):
# Update the convolution array
c[i + j] += (a[i] * b[j]) % MOD
# Print the convolution array c[]
for k in range(len(c)):
c[k] %= MOD
print(c[k], end = " ")
# Driver Code
if __name__ == '__main__':
A = [1, 2, 3, 4]
B = [5, 6, 7, 8, 9]
findConvolution(A, B)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG
{
static int MOD = 998244353;
// Function to generate a convolution
// array of two given arrays
static void findConvolution(int[] a,
int[] b)
{
// Stores the size of arrays
int n = a.Length, m = b.Length;
// Stores the final array
int[] c = new int[(n + m - 1)];
// Traverse the two given arrays
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
// Update the convolution array
c[i + j] += (a[i] * b[j]) % MOD;
}
}
// Print the convolution array c[]
for (int k = 0; k < c.Length; ++k) {
c[k] %= MOD;
Console.Write(c[k] + " ");
}
}
// Driver Code
public static void Main(String[] args)
{
int[] A = { 1, 2, 3, 4 };
int[] B = { 5, 6, 7, 8, 9 };
findConvolution(A, B);
}
}
// This code is contributed by code_hunt.
JavaScript
<script>
// Javascript program for the above approach
let MOD = 998244353;
// Function to generate a convolution
// array of two given arrays
function findConvolution(a, b)
{
// Stores the size of arrays
let n = a.length, m = b.length;
// Stores the final array
let c = [];
for(let i = 0; i < n + m - 1; ++i)
{
c[i] = 0;
}
// Traverse the two given arrays
for(let i = 0; i < n; ++i)
{
for(let j = 0; j < m; ++j)
{
// Update the convolution array
c[i + j] += (a[i] * b[j]) % MOD;
}
}
// Print the convolution array c[]
for(let k = 0; k < c.length; ++k)
{
c[k] %= MOD;
document.write(c[k] + " ");
}
}
// Driver Code
let A = [ 1, 2, 3, 4 ];
let B = [ 5, 6, 7, 8, 9 ];
findConvolution(A, B);
</script>
Output5 16 34 60 70 70 59 36
Time Complexity: O(N*M)
Auxiliary Space: O(N+M)
Efficient Approach: To optimize the above approach, the idea is to use the Number-Theoretic Transform (NTT) which is similar to Fast Fourier transform (FFT) for polynomial multiplication, which can work under modulo operations. The problem can be solved by using the same concept of iterative FFT to perform NTT on the given arrays as the same properties hold for the Nth roots of unity in modular arithmetic.
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 998244353, maxn = 3e6;
ll a[maxn], b[maxn];
// Iterative FFT function to compute
// the DFT of given coefficient vector
void fft(ll w0, ll n, ll* a)
{
// Do bit reversal of the given array
for (ll i = 0, j = 0; i < n; i++) {
// Swap a[i] and a[j]
if (i < j)
swap(a[i], a[j]);
// Right Shift N by 1
ll bit = n >> 1;
for (; j & bit; bit >>= 1)
j ^= bit;
j ^= bit;
}
// Perform the iterative FFT
for (ll len = 2; len <= n; len <<= 1) {
ll wlen = w0;
for (ll aux = n; aux > len; aux >>= 1) {
wlen = wlen * wlen % mod;
}
for (ll bat = 0; bat + len <= n; bat += len) {
for (ll i = bat, w = 1; i < bat + len / 2;
i++, w = w * wlen % mod) {
ll u = a[i], v = w * a[i + len / 2] % mod;
// Update the value of a[i]
a[i] = (u + v) % mod,
// Update the value
// of a[i + len/2]
a[i + len / 2]
= ((u - v) % mod + mod) % mod;
}
}
}
}
// Function to find (a ^ x) % mod
ll binpow(ll a, ll x)
{
// Stores the result of a ^ x
ll ans = 1;
// Iterate over the value of x
for (; x; x /= 2, a = a * a % mod) {
// If x is odd
if (x & 1)
ans = ans * a % mod;
}
// Return the resultant value
return ans;
}
// Function to find the
// inverse of a % mod
ll inv(ll a) { return binpow(a, mod - 2); }
// Function to find the
// convolution of two arrays
void findConvolution(ll a[], ll b[], ll n, ll m)
{
// Stores the first power of 2
// greater than or equal to n + m
ll _n = 1ll << 64 - __builtin_clzll(n + m);
// Stores the primitive root
ll w = 15311432;
for (ll aux = 1 << 23; aux > _n; aux >>= 1)
w = w * w % mod;
// Convert arrays a[] and
// b[] to point value form
fft(w, _n, a);
fft(w, _n, b);
// Perform multiplication
for (ll i = 0; i < _n; i++)
a[i] = a[i] * b[i] % mod;
// Perform inverse fft to
// recover final array
fft(inv(w), _n, a);
for (ll i = 0; i < _n; i++)
a[i] = a[i] * inv(_n) % mod;
// Print the convolution
for (ll i = 0; i < n + m - 1; i++)
cout << a[i] << " ";
}
// Driver Code
int main()
{
// Given size of the arrays
ll N = 4, M = 5;
// Fill the arrays
for (ll i = 0; i < N; i++)
a[i] = i + 1;
for (ll i = 0; i < M; i++)
b[i] = 5 + i;
findConvolution(a, b, N, M);
return 0;
}
Java
import java.math.BigInteger;
public class GFG {
public static final long mod = 998244353;
public static final int maxn = 3000000;
public static long[] a = new long[maxn];
public static long[] b = new long[maxn];
// Function to find the next power of 2 using
// bit masking
public static int nextPowerOf2(int n)
{
// if n is a power of two simply return it
if ((n & (n - 1)) == 0)
return n;
// else set only the left bit of most significant
// bit as in Java right shift is filled with most
// significant bit we consider
return 0x40000000
>> (Integer.numberOfLeadingZeros(n) - 2);
}
// Iterative fft function to compute
// the DFT of given coefficient vector
public static void fft(long w0, long n, long[] a)
{
// Do bit reversal of the given array
for (long i = 0, j = 0; i < n; i++) {
// Swap a[i] and a[j]
if (i < j) {
long temp = a[(int)i];
a[(int)i] = a[(int)j];
a[(int)j] = temp;
}
// Right Shift N by 1
long bit = n >> 1;
for (; (j & bit) != 0; bit >>= 1)
j ^= bit;
j ^= bit;
}
// Perform the iterative fft
for (long len = 2; len <= n; len <<= 1) {
long wlen = w0;
for (long aux = n; aux > len; aux >>= 1) {
wlen = wlen * wlen % mod;
}
for (long bat = 0; bat + len <= n; bat += len) {
for (long i = bat, w = 1; i < bat + len / 2;
i++, w = w * wlen % mod) {
long u = a[(int)i],
v
= w * a[(int)(i + len / 2)] % mod;
// Update the value of a[i]
a[(int)i] = (u + v) % mod;
// Update the value
// of a[i + len/2]
a[(int)(i + len / 2)]
= ((u - v) % mod + mod) % mod;
}
}
}
}
// Function to find (a ^ x) % mod
public static long binpow(long a, long x)
{
// Stores the result of a ^ x
long ans = 1;
// Iterate over the value of x
for (; x != 0; x /= 2, a = a * a % mod) {
// If x is odd
if ((x & 1) != 0)
ans = ans * a % mod;
}
// Return the resultant value
return ans;
}
// Function to find the
// inverse of a % mod
public static long inv(long a)
{
return binpow(a, mod - 2);
}
// Function to find the
// convolution of two arrays
static void FindConvolution(long[] a, long[] b, int n,
int m)
{
// Stores the first power of 2
// greater than or equal to n + m
int _n = nextPowerOf2(n + m);
// Stores the primitive root
long w = 15311432;
for (int aux = 1 << 23; aux > _n; aux >>= 1)
w = w * w % mod;
// Convert arrays a[] and b[] to point value form
fft(w, _n, a);
fft(w, _n, b);
// Perform multiplication
for (int i = 0; i < _n; i++)
a[i] = a[i] * b[i] % mod;
// Perform inverse fft to recover final array
fft(inv(w), _n, a);
for (int i = 0; i < _n; i++)
a[i] = a[i] * inv(_n) % mod;
for (int i = 0; i < n + m - 1; i++)
System.out.print(a[i] + " ");
}
public static void main(String[] args)
{
// Given size of the arrays
int N = 4, M = 5;
// Fill the arrays
for (int i = 0; i < N; i++)
a[i] = i + 1;
for (int i = 0; i < M; i++)
b[i] = 5 + i;
FindConvolution(a, b, N, M);
}
}
Python3
import math
mod = 998244353
maxn = 300000
a = [0] * maxn
b = [0] * maxn
# Iterative FFT function to compute
# the DFT of given coefficient list
def fft(w0, n, a):
# Do bit reversal of the given list
j = 0
for i in range(n):
# Swap a[i] and a[j]
if i < j:
a[i], a[j] = a[j], a[i]
# Right Shift N by 1
bit = n >> 1
while j & bit:
j ^= bit
bit >>= 1
j ^= bit
# Perform the iterative FFT
length = 2
while length <= n:
wlen = w0
aux = n
while aux > length:
wlen = wlen*wlen % mod
aux = aux >> 1
for bat in range(0, n - length + 1, length):
w = 1
for i in range(bat, bat + length // 2):
u, v = a[i], w * a[i + length // 2] % mod
# Update the value of a[i]
a[i] = (u + v) % mod
# Update the value of a[i + len/2]
a[i + length // 2] = ((u - v) % mod + mod) % mod
w = w * wlen % mod
length <<= 1
# Function to find (a ^ x) % mod
def binpow(a, x):
# Stores the result of a ^ x
ans = 1
# Iterate over the value of x
while x:
# If x is odd
if x & 1:
ans = ans * a % mod
x >>= 1
a = a * a % mod
# Return the resultant value
return ans
# Function to find the inverse of a % mod
def inv(a):
return binpow(a, mod - 2)
# Function to find the convolution of two list
def findConvolution(a, b, n, m):
# Stores the first power of 2 greater than or equal to n + m
_n = 1 << math.ceil(math.log2(n+m))
# Stores the primitive root
w = 15311432
aux = 1 << 23
while aux > _n:
w = w * w % mod
aux >>= 1
# Convert list a[] and b[] to point value form
fft(w, _n, a)
fft(w, _n, b)
# Perform multiplication
for i in range(_n):
a[i] = a[i] * b[i] % mod
# Perform inverse fft to recover final list
fft(inv(w), _n, a)
for i in range(_n):
a[i] = a[i] * inv(_n) % mod
# Print the convolution
for i in range(n + m - 1):
print(a[i], end=" ")
# Driver Code
if __name__ == "__main__":
# Given size of the arrays
N, M = 4, 5
# Fill the list
for i in range(N):
a[i] = i + 1
for i in range(M):
b[i] = 5 + i
findConvolution(a, b, N, M)
# Contributed by Ayush Panwar
C#
using System;
using System.Numerics;
using System.Collections.Generic;
public class GFG {
public const long mod = 998244353;
public const int maxn = 3000000;
public static long[] a = new long[maxn];
public static long[] b = new long[maxn];
static int nextPowerOf2(int N)
{
// if N is a power of two simply return it
if ((N & (N - 1)) == 0)
return N;
// else set only the left bit of most significant
// bit
return Convert.ToInt32(
"1"
+ new string('0',
Convert.ToString(N, 2).Length),
2);
}
// Iterative fft function to compute
// the DFT of given coefficient vector
public static void fft(long w0, long n, long[] a)
{
// Do bit reversal of the given array
for (long i = 0, j = 0; i < n; i++) {
// Swap a[i] and a[j]
if (i < j) {
long temp = a[i];
a[i] = a[j];
a[j] = temp;
}
// Right Shift N by 1
long bit = n >> 1;
for (; (j & bit) != 0; bit >>= 1)
j ^= bit;
j ^= bit;
}
// Perform the iterative fft
for (long len = 2; len <= n; len <<= 1) {
long wlen = w0;
for (long aux = n; aux > len; aux >>= 1) {
wlen = wlen * wlen % mod;
}
for (long bat = 0; bat + len <= n; bat += len) {
for (long i = bat, w = 1; i < bat + len / 2;
i++, w = w * wlen % mod) {
long u = a[i],
v = w * a[i + len / 2] % mod;
// Update the value of a[i]
a[i] = (u + v) % mod;
// Update the value
// of a[i + len/2]
a[i + len / 2]
= ((u - v) % mod + mod) % mod;
}
}
}
}
// Function to find (a ^ x) % mod
public static long binpow(long a, long x)
{
// Stores the result of a ^ x
long ans = 1;
// Iterate over the value of x
for (; x != 0; x /= 2, a = a * a % mod) {
// If x is odd
if ((x & 1) != 0)
ans = ans * a % mod;
}
// Return the resultant value
return ans;
}
// Function to find the
// inverse of a % mod
public static long inv(long a)
{
return binpow(a, mod - 2);
}
// Function to find the
// convolution of two arrays
// Function to find the convolution of two arrays
static void FindConvolution(long[] a, long[] b, int n,
int m)
{
// Stores the first power of 2
// greater than or equal to n + m
int _n = nextPowerOf2(n + m);
// Stores the primitive root
long w = 15311432;
for (int aux = 1 << 23; aux > _n; aux >>= 1)
w = w * w % mod;
// Convert arrays a[] and b[] to point value form
fft(w, _n, a);
fft(w, _n, b);
// Perform multiplication
for (int i = 0; i < _n; i++)
a[i] = a[i] * b[i] % mod;
// Perform inverse fft to recover final array
fft(inv(w), _n, a);
for (int i = 0; i < _n; i++)
a[i] = a[i] * inv(_n) % mod;
for (int i = 0; i < n + m - 1; i++)
Console.Write(a[i] + " ");
}
public static void Main(string[] args)
{
// Given size of the arrays
int N = 4, M = 5;
// Fill the arrays
for (int i = 0; i < N; i++)
a[i] = i + 1;
for (int i = 0; i < M; i++)
b[i] = 5 + i;
FindConvolution(a, b, N, M);
}
}
Output5 16 34 60 70 70 59 36
Time Complexity: O(N*log(N))
Auxiliary Space: O(N + M)
Similar Reads
Generate an array having sum of Bitwise OR of same-indexed elements with given array equal to K
Given an array arr[] consisting of N integers and an integer K, the task is to print an array generated such that the sum of Bitwise OR of same indexed elements of the generated array with the given array is equal to K. If it is not possible to generate such an array, then print "-1". Examples: Inpu
7 min read
Generate an array B[] from the given array A[] which satisfies the given conditions
Given an array A[] of N integers such that A[0] + A[1] + A[2] + ... A[N - 1] = 0. The task is to generate an array B[] such that B[i] is either ?A[i] / 2? or ?A[i] / 2? for all valid i and B[0] + B[1] + B[2] + ... + B[N - 1] = 0. Examples: Input: A[] = {1, 2, -5, 3, -1} Output: 0 1 -2 1 0Input: A[]
6 min read
Mean of array generated by products of all pairs of the given array
Given an array arr[] consisting of N integers, the task is to find the mean of the array formed by the products of unordered pairs of the given array. Examples: Input: arr[] = {2, 5, 7}Output: 19.67Explanation:Product of unordered pairs of array arr[] are 2 * 5 = 10, 2 * 7 = 14 and 5 * 7 = 35.Theref
12 min read
Find resultant Array after applying Convolution on given array using given mask
Given two arrays arr[] containing N integers and a mask[] of an odd size. The task is to replace every array element with the value computed by performing the same convolution on the array. Examples: Input: arr[] = {9, 7, 3, 9, 1, 8, 11}, mask[]={1, 2, -1}Output: 11 20 4 20 3 6 30 Explanation: Follo
5 min read
Generate all possible sorted arrays from alternate elements of two given sorted arrays
Given two sorted arrays A and B, generate all possible arrays such that the first element is taken from A then from B then from A, and so on in increasing order till the arrays are exhausted. The generated arrays should end with an element from B. Example: A = {10, 15, 25} B = {1, 5, 20, 30} The res
12 min read
Program to concatenate two given Matrices of same size
Given two matrices A and B of size M x N, the task is to concatenate them into one matrix.Concatenation of matrix: The process of appending elements of every row of the matrix one after the other is known as the Concatenation of matrix. Examples: Input: A[][] = {{1, 2}, {3, 4}}, B[][] = {{5, 6}, {7,
6 min read
Count pairs from two arrays having sum equal to K
Given an integer K and two arrays A1 and A2, the task is to return the total number of pairs (one element from A1 and one element from A2) with a sum equal to K. Note: Arrays can have duplicate elements. We consider every pair as different, the only constraint is, an element (of any array) can parti
6 min read
Maximum array from two given arrays keeping order same
Given two same-sized arrays a[] and b[] (each containing distinct elements individually, but they may have some common elements between them). The task is to create a third array res[] of the same size n that includes maximum n elements combined from both arrays.Start by including elements from a[]
8 min read
Maximize array sum by concatenating corresponding elements of given two arrays
Given two array A[] and B[] of the same length, the task is to find the maximum array sum that can be formed by joining the corresponding elements of the array in any order. Input: A[] = {1, 2, 3, 4, 5}, B[] = {3, 2, 1, 4, 5} Output: 183 Explanation: Numbers formed by joining the digits of the eleme
8 min read
Jagged Array or Array of Arrays in C with Examples
Prerequisite: Arrays in CJagged array is array of arrays such that member arrays can be of different sizes, i.e., we can create a 2-D array but with a variable number of columns in each row. These type of arrays are also known as Jagged arrays. Example:arr[][] = { {0, 1, 2}, {6, 4}, {1, 7, 6, 8, 9},
3 min read