Expressing factorial n as sum of consecutive numbers
Last Updated :
10 Jan, 2023
Given two numbers N and M. Find the number of ways in which factorial N can be expressed as a sum of two or more consecutive numbers. Print the result modulo M.
Examples:
Input : N = 3, M = 7
Output : 1
Explanation: 3! can be expressed
in one way, i.e. 1 + 2 + 3 = 6.
Hence 1 % 7 = 1
Input : N = 4, M = 7
Output : 1
Explanation: 4! can be expressed
in one way, i.e. 7 + 8 + 9 = 24
Hence 1 % 7 = 1
A simple solution is to first compute factorial, then count number of ways to represent factorial as sum of consecutive numbers using Count ways to express a number as sum of consecutive numbers. This solution causes overflow.
Below is a better solution to avoid overflow.
Let us consider that sum of r consecutive numbers be expressed as:
(a + 1) + (a + 2) + (a + 3) + ... + (a + r), which simplifies as (r * (r + 2*a + 1)) / 2
Hence, (a + 1) + (a + 2) + (a + 3) + ... + (a + r) = (r * (r + 2*a + 1)) / 2. Since the above expression is equal to factorial N, we write it as
2 * N! = r * (r + 2*a + 1)
Instead of counting all the pairs (r, a), we will count all pairs (r, r + 2*a + 1). Now, we are just counting all ordered pairs (X, Y) with XY = 2 * N! where X < Y and X, Y have different parity, that means if (r) is even, (r + 2*a + 1) is odd or if (r) is odd then (r + 2*a + 1) is even. This is equivalent to finding the odd divisors of 2 * N! which will be same as odd divisors of N!.
For counting the number of divisors in N!, we calculate the power of primes in factorization and total count of divisors become (p1 + 1) * (p2 + 1) * ... * (pn + 1). To calculate the largest power of a prime in N!, we will use legendre's formula.
\nu _{p}(n!)=\sum _{{i=1}}^{{\infty }}\left\lfloor {\frac {n}{p^{i}}}\right\rfloor,
Below is the implementation of the above approach.
C++
// CPP program to count number of
// ways we can express a factorial
// as sum of consecutive numbers
#include <bits/stdc++.h>
using namespace std;
#define MAX 50002
vector<int> primes;
// sieve of Eratosthenes to compute
// the prime numbers
void sieve()
{
bool isPrime[MAX];
memset(isPrime, true, sizeof(isPrime));
for (int p = 2; p * p < MAX; p++) {
if (isPrime[p] == true) {
for (int i = p * 2; i < MAX; i += p)
isPrime[i] = false;
}
}
// Store all prime numbers
for (int p = 2; p < MAX; p++)
if (isPrime[p])
primes.push_back(p);
}
// function to calculate the largest
// power of a prime in a number
long long int power(long long int x,
long long int y)
{
long long int count = 0;
long long int z = y;
while (x >= z) {
count += (x / z);
z *= y;
}
return count;
}
// Modular multiplication to avoid
// the overflow of multiplication
// Please see below for details
// https://www.geeksforgeeks.org/how-to-avoid-overflow-in-modular-multiplication/
long long int modMult(long long int a,
long long int b,
long long int mod)
{
long long int res = 0;
a = a % mod;
while (b > 0) {
if (b % 2 == 1)
res = (res + a) % mod;
a = (a * 2) % mod;
b /= 2;
}
return res % mod;
}
// Returns count of ways to express n!
// as sum of consecutives.
long long int countWays(long long int n,
long long int m)
{
long long int ans = 1;
// We skip 2 (First prime) as we need to
// consider only odd primes
for (int i = 1; i < primes.size(); i++) {
// compute the largest power of prime
long long int powers = power(n, primes[i]);
// if the power of current prime number
// is zero in N!, power of primes greater
// than current prime number will also
// be zero, so break out from the loop
if (powers == 0)
break;
// multiply the result at every step
ans = modMult(ans, powers + 1, m) % m;
}
// subtract 1 to exclude the case of 1
// being an odd divisor
if (((ans - 1) % m) < 0)
return (ans - 1 + m) % m;
else
return (ans - 1) % m;
}
// Driver Code
int main()
{
sieve();
long long int n = 4, m = 7;
cout << countWays(n, m);
return 0;
}
Java
// Java program to count number of
// ways we can express a factorial
// as sum of consecutive numbers
import java.util.*;
class GFG {
static int MAX = 50002;
static ArrayList<Integer> primes
= new ArrayList<Integer>();
// sieve of Eratosthenes to compute
// the prime numbers
public static void sieve()
{
boolean isPrime[] = new boolean[MAX];
for(int i = 0; i < MAX; i++)
isPrime[i] = true;
for (int p = 2; p * p < MAX; p++) {
if (isPrime[p] == true) {
for (int i = p * 2; i < MAX; i += p)
isPrime[i] = false;
}
}
// Store all prime numbers
for (int p = 2; p < MAX; p++)
if (isPrime[p] == true)
primes.add(p);
}
// function to calculate the largest
// power of a prime in a number
public static int power(int x, int y)
{
int count = 0;
int z = y;
while (x >= z) {
count += (x / z);
z *= y;
}
return count;
}
// Modular multiplication to avoid
// the overflow of multiplication
// Please see below for details
// https://www.geeksforgeeks.org/how-to-avoid-overflow-in-modular-multiplication/
public static int modMult(int a, int b, int mod)
{
int res = 0;
a = a % mod;
while (b > 0) {
if (b % 2 == 1)
res = (res + a) % mod;
a = (a * 2) % mod;
b /= 2;
}
return res % mod;
}
// Returns count of ways to express n!
// as sum of consecutives.
public static int countWays(int n, int m)
{
int ans = 1;
// We skip 2 (First prime) as we need to
// consider only odd primes
for (int i = 1; i < primes.size(); i++) {
// compute the largest power of prime
int powers = power(n, primes.get(i));
// if the power of current prime number
// is zero in N!, power of primes greater
// than current prime number will also
// be zero, so break out from the loop
if (powers == 0)
break;
// multiply the result at every step
ans = modMult(ans, powers + 1, m) % m;
}
// subtract 1 to exclude the case of 1
// being an odd divisor
if (((ans - 1) % m) < 0)
return (ans - 1 + m) % m;
else
return (ans - 1) % m;
}
//Driver function
public static void main (String[] args) {
sieve();
int n = 4, m = 7;
System.out.println(countWays(n,m));
}
}
// This code is contributed by akash1295.
Python 3
# Python 3 program to count number of
# ways we can express a factorial
# as sum of consecutive numbers
MAX = 50002;
primes = []
# sieve of Eratosthenes to compute
# the prime numbers
def sieve():
isPrime = [True]*(MAX)
p = 2
while p * p < MAX :
if (isPrime[p] == True):
for i in range( p * 2,MAX, p):
isPrime[i] = False
p+=1
# Store all prime numbers
for p in range( 2,MAX):
if (isPrime[p]):
primes.append(p)
# function to calculate the largest
# power of a prime in a number
def power( x, y):
count = 0
z = y
while (x >= z):
count += (x // z)
z *= y
return count
# Modular multiplication to avoid
# the overflow of multiplication
# Please see below for details
# https://www.geeksforgeeks.org/how-to-avoid-overflow-in-modular-multiplication/
def modMult(a, b,mod):
res = 0
a = a % mod
while (b > 0):
if (b % 2 == 1):
res = (res + a) % mod
a = (a * 2) % mod
b //= 2
return res % mod
# Returns count of ways to express n!
# as sum of consecutives.
def countWays(n,m):
ans = 1
# We skip 2 (First prime) as we need to
# consider only odd primes
for i in range(1,len(primes)):
# compute the largest power of prime
powers = power(n, primes[i])
# if the power of current prime number
# is zero in N!, power of primes greater
# than current prime number will also
# be zero, so break out from the loop
if (powers == 0):
break
# multiply the result at every step
ans = modMult(ans, powers + 1, m) % m
# subtract 1 to exclude the case of 1
# being an odd divisor
if (((ans - 1) % m) < 0):
return (ans - 1 + m) % m
else:
return (ans - 1) % m
# Driver Code
if __name__ == "__main__":
sieve()
n = 4
m = 7
print(countWays(n, m))
# This code is contributed by ChitraNayal
C#
// C# program to count number of
// ways we can express a factorial
// as sum of consecutive numbers
using System ;
using System.Collections;
class GFG {
static int MAX = 50002;
static ArrayList primes = new ArrayList ();
// sieve of Eratosthenes to compute
// the prime numbers
public static void sieve()
{
bool []isPrime = new bool[MAX];
for(int i = 0; i < MAX; i++)
isPrime[i] = true;
for (int p = 2; p * p < MAX; p++) {
if (isPrime[p] == true) {
for (int i = p * 2; i < MAX; i += p)
isPrime[i] = false;
}
}
// Store all prime numbers
for (int p = 2; p < MAX; p++)
if (isPrime[p] == true)
primes.Add(p);
}
// function to calculate the largest
// power of a prime in a number
public static int power_prime(int x, int y)
{
int count = 0;
int z = y;
while (x >= z) {
count += (x / z);
z *= y;
}
return count;
}
// Modular multiplication to avoid
// the overflow of multiplication
// Please see below for details
// https://www.geeksforgeeks.org/how-to-avoid-overflow-in-modular-multiplication/
public static int modMult(int a, int b, int mod)
{
int res = 0;
a = a % mod;
while (b > 0) {
if (b % 2 == 1)
res = (res + a) % mod;
a = (a * 2) % mod;
b /= 2;
}
return res % mod;
}
// Returns count of ways to express n!
// as sum of consecutives.
public static int countWays(int n, int m)
{
int ans = 1;
// We skip 2 (First prime) as we need to
// consider only odd primes
for (int i = 1; i < primes.Count; i++) {
// compute the largest power of prime
int powers = power_prime(n, Convert.ToInt32(primes[i]));
// if the power of current prime number
// is zero in N!, power of primes greater
// than current prime number will also
// be zero, so break out from the loop
if (powers == 0)
break;
// multiply the result at every step
ans = modMult(ans, powers + 1, m) % m;
}
// subtract 1 to exclude the case of 1
// being an odd divisor
if (((ans - 1) % m) < 0)
return (ans - 1 + m) % m;
else
return (ans - 1) % m;
}
//Driver function
public static void Main () {
sieve();
int n = 4, m = 7;
Console.WriteLine(countWays(n,m));
}
}
// This code is contributed by Ryuga
JavaScript
<script>
// Javascript program to count number of
// ways we can express a factorial
// as sum of consecutive numbers
let MAX = 50002;
let primes = [];
// sieve of Eratosthenes to compute
// the prime numbers
function sieve()
{
let isPrime = new Array(MAX);
for(let i = 0; i < MAX; i++)
isPrime[i] = true;
for (let p = 2; p * p < MAX; p++)
{
if (isPrime[p] == true)
{
for (let i = p * 2; i < MAX; i += p)
isPrime[i] = false;
}
}
// Store all prime numbers
for (let p = 2; p < MAX; p++)
if (isPrime[p] == true)
primes.push(p);
}
// function to calculate the largest
// power of a prime in a number
function power(x,y)
{
let count = 0;
let z = y;
while (x >= z) {
count += Math.floor(x / z);
z *= y;
}
return count;
}
// Modular multiplication to avoid
// the overflow of multiplication
// Please see below for details
// https://www.geeksforgeeks.org/how-to-avoid-overflow-in-modular-multiplication/
function modMult(a,b,mod)
{
let res = 0;
a = a % mod;
while (b > 0) {
if (b % 2 == 1)
res = (res + a) % mod;
a = (a * 2) % mod;
b = Math.floor(b/2);
}
return res % mod;
}
// Returns count of ways to express n!
// as sum of consecutives.
function countWays(n,m)
{
let ans = 1;
// We skip 2 (First prime) as we need to
// consider only odd primes
for (let i = 1; i < primes.length; i++) {
// compute the largest power of prime
let powers = power(n, primes[i]);
// if the power of current prime number
// is zero in N!, power of primes greater
// than current prime number will also
// be zero, so break out from the loop
if (powers == 0)
break;
// multiply the result at every step
ans = modMult(ans, powers + 1, m) % m;
}
// subtract 1 to exclude the case of 1
// being an odd divisor
if (((ans - 1) % m) < 0)
return (ans - 1 + m) % m;
else
return (ans - 1) % m;
}
//Driver function
sieve();
let n = 4, m = 7;
document.write(countWays(n,m));
// This code is contributed by avanitrachhadiya2155
</script>
Time Complexity: O(MAX*log(log(MAX))+M*log(K)) where MAX=5002, M is the number of primes less than MAX(i.e 5002), and K is the greatest prime number less than MAX.
Auxiliary Space: O(MAX)
Similar Reads
DSA Tutorial - Learn Data Structures and Algorithms DSA (Data Structures and Algorithms) is the study of organizing data efficiently using data structures like arrays, stacks, and trees, paired with step-by-step procedures (or algorithms) to solve problems effectively. Data structures manage how data is stored and accessed, while algorithms focus on
7 min read
Quick Sort QuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. It works on the principle of divide and conquer, breaking down the problem into s
12 min read
Merge Sort - Data Structure and Algorithms Tutorials Merge sort is a popular sorting algorithm known for its efficiency and stability. It follows the divide-and-conquer approach. It works by recursively dividing the input array into two halves, recursively sorting the two halves and finally merging them back together to obtain the sorted array. Merge
14 min read
SQL Commands | DDL, DQL, DML, DCL and TCL Commands SQL commands are crucial for managing databases effectively. These commands are divided into categories such as Data Definition Language (DDL), Data Manipulation Language (DML), Data Control Language (DCL), Data Query Language (DQL), and Transaction Control Language (TCL). In this article, we will e
7 min read
Data Structures Tutorial Data structures are the fundamental building blocks of computer programming. They define how data is organized, stored, and manipulated within a program. Understanding data structures is very important for developing efficient and effective algorithms. What is Data Structure?A data structure is a st
2 min read
Bubble Sort Algorithm Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in the wrong order. This algorithm is not suitable for large data sets as its average and worst-case time complexity are quite high.We sort the array using multiple passes. After the fir
8 min read
Breadth First Search or BFS for a Graph Given a undirected graph represented by an adjacency list adj, where each adj[i] represents the list of vertices connected to vertex i. Perform a Breadth First Search (BFS) traversal starting from vertex 0, visiting vertices from left to right according to the adjacency list, and return a list conta
15+ min read
Binary Search Algorithm - Iterative and Recursive Implementation Binary Search Algorithm is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(log N). Binary Search AlgorithmConditions to apply Binary Searc
15 min read
Insertion Sort Algorithm Insertion sort is a simple sorting algorithm that works by iteratively inserting each element of an unsorted list into its correct position in a sorted portion of the list. It is like sorting playing cards in your hands. You split the cards into two groups: the sorted cards and the unsorted cards. T
9 min read
Array Data Structure Guide In this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
4 min read