Skip to content

Commit e992b26

Browse files
committed
Range Prime Factorization Added
1 parent ec42d41 commit e992b26

File tree

2 files changed

+240
-13
lines changed

2 files changed

+240
-13
lines changed
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
2+
/**
3+
4+
Range Prime Factorization (OPTIMIZED)
5+
===============================
6+
7+
Bruteforce Range Factorization
8+
------------------------------
9+
Segmented Sieve + Bruteforce prime factorization
10+
O( (R-L+1) log(logR) ) + O( (R-L) * (sqrt(N)/log(sqrt(N)) * log(N)) )
11+
12+
For larger N value (like 1e12) it will get TLE
13+
14+
Optimization Idea 1 (will eventually fail) :
15+
--------------------------------------------
16+
using SPF (smallest prime factors) we could do prime factorization in logN , but we can't find all spf in [1,1e12] in memory limit
17+
will optimize for lower values of N
18+
19+
Optimization Idea 2 :
20+
--------------------
21+
modifying segmented sieve to get all the prime factors of a number without the powers
22+
and later use this information to Factorize in logN
23+
As we don't need to iterate upto logN for every Number , the factorization complexity will reduce to logN
24+
25+
**/
26+
27+
28+
/** Which of the favors of your Lord will you deny ? **/
29+
30+
#include<bits/stdc++.h>
31+
using namespace std;
32+
33+
#define LL long long
34+
#define PII pair<int,int>
35+
#define PLL pair<LL,LL>
36+
#define F first
37+
#define S second
38+
39+
#define ALL(x) (x).begin(), (x).end()
40+
#define READ freopen("alu.txt", "r", stdin)
41+
#define WRITE freopen("vorta.txt", "w", stdout)
42+
43+
#ifndef ONLINE_JUDGE
44+
#define DBG(x) cout << __LINE__ << " says: " << #x << " = " << (x) << endl
45+
#else
46+
#define DBG(x)
47+
#define endl "\n"
48+
#endif
49+
50+
template<class T1, class T2>
51+
ostream &operator <<(ostream &os, pair<T1,T2>&p);
52+
template <class T>
53+
ostream &operator <<(ostream &os, vector<T>&v);
54+
template <class T>
55+
ostream &operator <<(ostream &os, set<T>&v);
56+
57+
inline void optimizeIO()
58+
{
59+
ios_base::sync_with_stdio(false);
60+
cin.tie(NULL);
61+
}
62+
63+
const int nmax = 2e5+7;
64+
65+
#define int long long
66+
67+
/**
68+
Segmented Sieve
69+
Range of [L,R] ~ 1e7 and R ~ 1e12
70+
**/
71+
72+
const int pnmax = 1e6+10; /** ~ sqrt(R) **/
73+
const int pnmax2 = 5e5+10; /** diff of R and L **/
74+
75+
LL LIM = 1e6+5; /** ~ sqrt(R) **/
76+
vector<LL>primes;
77+
bool isP[pnmax];
78+
bool isPFinal[pnmax2];
79+
80+
void sieve()
81+
{
82+
for(LL i=2; i<=LIM; i++)
83+
isP[i] = true;
84+
85+
for(LL i=2; i<=LIM; i++) /** If I don't want to know the primes , it is enough to loop upto sqrt(LIM) here **/
86+
{
87+
if(isP[i]==true)
88+
{
89+
primes.push_back(i);
90+
for(LL j=i*i; j<=LIM; j+=i)
91+
isP[j]=false;
92+
}
93+
}
94+
}
95+
96+
/** Prime Factorization **/
97+
vector<vector<LL>>factorization(pnmax2);
98+
99+
vector<LL> primeFactors(LL N,vector<LL>&factors_init)
100+
{
101+
vector<LL>factors;
102+
for(auto PF:factors_init) /// stop at sqrt(N), but N can get smaller
103+
{
104+
while (N % PF == 0)
105+
{
106+
N /= PF; /// remove this PF
107+
factors.push_back(PF);
108+
}
109+
}
110+
if (N != 1) factors.push_back(N); /// special case if N is actually a prime
111+
112+
return factors;
113+
}
114+
115+
/** Number of Divisors **/
116+
LL NOD[pnmax2];
117+
118+
LL number_of_Divisors(LL N,vector<LL>&factors_init)
119+
{
120+
LL ans = 1;
121+
122+
for(auto PF:factors_init)
123+
{
124+
LL power = 0; /// count the power
125+
while (N % PF == 0)
126+
{
127+
N /= PF;
128+
power++;
129+
}
130+
ans *= (power + 1); /// according to the formula
131+
}
132+
133+
if (N != 1) ans *= 2; /// (last factor has pow = 1, we add 1 to it)
134+
135+
return ans;
136+
}
137+
138+
void segmented_sieve(LL L,LL R)
139+
{
140+
vector<vector<int>>factors_init(pnmax2);
141+
142+
/// Step 1: we will identify all the prime factors of Numbers in the range [l,r] . But we will not know the powers . That we will do in Step 2
143+
for(auto p:primes)
144+
{
145+
if(p*p > R)
146+
break;
147+
148+
LL j=p*p;
149+
150+
if(j<L)
151+
j=((L+p-1)/p)*p;
152+
153+
for(; j<=R; j+=p)
154+
factors_init[j-L].push_back(p);
155+
156+
}
157+
158+
/// Step 2 : Find the powers
159+
for(LL i=L; i<=R; i++)
160+
{
161+
NOD[i-L] = number_of_Divisors(i,factors_init[i-L]);
162+
factorization[i-L] = primeFactors(i,factors_init[i-L]);
163+
}
164+
}
165+
166+
int32_t main()
167+
{
168+
optimizeIO();
169+
170+
sieve();
171+
172+
int tc;
173+
cin>>tc;
174+
175+
while(tc--)
176+
{
177+
LL l,r;
178+
cin>>l>>r;
179+
180+
segmented_sieve(l,r);
181+
182+
for(int i=l;i<=r;i++)
183+
{
184+
cout<<"Number : "<<i<<endl;
185+
cout<<"NOD : "<<NOD[i-l]<<endl;
186+
cout<<"Factorization : "<<endl;
187+
DBG(factorization[i-l]);
188+
}
189+
}
190+
191+
return 0;
192+
}
193+
194+
/**
195+
196+
**/
197+
198+
template<class T1, class T2>
199+
ostream &operator <<(ostream &os, pair<T1,T2>&p)
200+
{
201+
os<<"{"<<p.first<<", "<<p.second<<"} ";
202+
return os;
203+
}
204+
template <class T>
205+
ostream &operator <<(ostream &os, vector<T>&v)
206+
{
207+
os<<"[ ";
208+
for(T i:v)
209+
{
210+
os<<i<<" " ;
211+
}
212+
os<<" ]";
213+
return os;
214+
}
215+
216+
template <class T>
217+
ostream &operator <<(ostream &os, set<T>&v)
218+
{
219+
os<<"[ ";
220+
for(T i:v)
221+
{
222+
os<<i<<" ";
223+
}
224+
os<<" ]";
225+
return os;
226+
}

README.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,12 @@
7070
* ***Prime Factorization***
7171
* [Using all primes](Algorithm/25%20Prime%20Factorization.cpp) : **O( (sqrt(N)/log(sqrt(N)) * logN )**
7272
* [Using only smallest prime factor](Algorithm/35%20Prime%20Factorization%20using%20SPF.cpp) : **O(logN)**
73+
* [Prime Factorization in a range **[L,R]** ](/Algorithm/53%20Prime%20Factorization%20in%20a%20Range.cpp) **O( (R-L) * logN ) _[Optimized]_**
7374
* ***Divisors***
7475
* [Number of Divisors](Algorithm/26%20Divisors.cpp)
7576
* [Cumulative Sum of Number of Divisors](Algorithm/26%20Divisors.cpp)
7677
* [Sum of Divisors](Algorithm/26%20Divisors.cpp)
7778
* [Cumulative Sum of Sum of Divisors](Algorithm/26%20Divisors.cpp)
78-
* [All Prime Divisors](Algorithm/36%20Find%20All%20Prime%20Divisors%20of%20N.cpp)
79-
: **O( sqrt (N) )**
8079
* [***Euler Totient***](Algorithm/27%20Euler%20Totient.cpp)
8180
* ***Linear Diophantine***
8281
* [2 Variable](Algorithm/29%20Linear_Diophantine.cpp)
@@ -295,20 +294,22 @@
295294
* [N-digit binary strings without any consecutive 1’s](Dynamic%20Programming/18%20Count%20N%20digit%20binary%20string%20without%20consecutive%201's.cpp)
296295

297296
# Miscellaneous
298-
* ***Operator Overloading for sorting / STL Data Structure***
299-
* [Using Comparator ***functions / structure***](Miscellaneous/01%20Operator%20Overloading%20for%20Sorting%20(Part%201).cpp)
300-
* [Overloading **<** operator](Miscellaneous/01%20Operator%20Overloading%20for%20Sorting%20(Part%202).cpp)
301-
* [Overloading **>** operator](Miscellaneous/01%20Operator%20Overloading%20for%20Sorting%20(Part%203).cpp)
297+
- ***Operator Overloading for sorting / STL Data Structure***
298+
- [Using Comparator ***functions / structure***](Miscellaneous/01%20Operator%20Overloading%20for%20Sorting%20(Part%201).cpp)
299+
- [Overloading **<** operator](Miscellaneous/01%20Operator%20Overloading%20for%20Sorting%20(Part%202).cpp)
300+
- [Overloading **>** operator](Miscellaneous/01%20Operator%20Overloading%20for%20Sorting%20(Part%203).cpp)
302301

303-
* [***BIg Integer Library***](Miscellaneous/06%20Big_Integer.cpp)
302+
- [_**Coordinate Compression**_](/Miscellaneous/07%20Coordinate%20Compression.cpp)
303+
304+
- [***BIG Integer Library***](Miscellaneous/06%20Big_Integer.cpp)
304305

305-
* ***Integer Root***
306-
* [Square Root *(Binary Search)*](Miscellaneous/04%20Square%20Root%20Binary%20Search.cpp) **(Modifiable to nth Root)**
307-
* [Fast Square & Cube Root](Miscellaneous/05%20Fast%20Integer%20Cube%20and%20Square%20Root.cpp)
306+
- ***Integer Root***
307+
- [Square Root *(Binary Search)*](Miscellaneous/04%20Square%20Root%20Binary%20Search.cpp) **(Modifiable to nth Root)**
308+
- [Fast Square & Cube Root](Miscellaneous/05%20Fast%20Integer%20Cube%20and%20Square%20Root.cpp)
308309

309-
* ***Geometry Template***
310-
* [Point & Line](Miscellaneous/02%20Geometry%20Template%20(Point%20%26%20Line).cpp)
311-
* [Rectangle](Miscellaneous/03%20Geometry%20Template%20(Rectangle).cpp)
310+
- ***Geometry Template***
311+
- [Point & Line](Miscellaneous/02%20Geometry%20Template%20(Point%20%26%20Line).cpp)
312+
- [Rectangle](Miscellaneous/03%20Geometry%20Template%20(Rectangle).cpp)
312313

313314

314315

0 commit comments

Comments
 (0)