-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsolution.cpp
More file actions
129 lines (99 loc) · 2.86 KB
/
Copy pathsolution.cpp
File metadata and controls
129 lines (99 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
class Solution
{
public:
// Segment tree to store LCM values
vector<long long> seg;
// Function to calculate GCD
long long gcd(long long a, long long b)
{
while (b)
{
long long temp = a % b;
a = b;
b = temp;
}
return a;
}
// Function to calculate LCM safely
long long lcm(long long a, long long b)
{
return (a / gcd(a, b)) * b;
}
// Build segment tree
void build(int idx, int low, int high, vector<int> &arr)
{
// Leaf node stores array value
if (low == high)
{
seg[idx] = arr[low];
return;
}
int mid = (low + high) / 2;
// Build left subtree
build(2 * idx + 1, low, mid, arr);
// Build right subtree
build(2 * idx + 2, mid + 1, high, arr);
// Store LCM of both children
seg[idx] = lcm(seg[2 * idx + 1], seg[2 * idx + 2]);
}
// Update one index
void update(int idx, int low, int high, int pos, int val)
{
// Reached target index
if (low == high)
{
seg[idx] = val;
return;
}
int mid = (low + high) / 2;
// Go to left side
if (pos <= mid)
update(2 * idx + 1, low, mid, pos, val);
// Go to right side
else
update(2 * idx + 2, mid + 1, high, pos, val);
// Recalculate current node
seg[idx] = lcm(seg[2 * idx + 1], seg[2 * idx + 2]);
}
// Query LCM in range
long long query(int idx, int low, int high, int l, int r)
{
// Completely outside range
if (high < l || low > r)
return 1;
// Completely inside range
if (low >= l && high <= r)
return seg[idx];
int mid = (low + high) / 2;
// Query left part
long long left = query(2 * idx + 1, low, mid, l, r);
// Query right part
long long right = query(2 * idx + 2, mid + 1, high, l, r);
// Merge both answers using LCM
return lcm(left, right);
}
vector<long long> RangeLCMQuery(vector<int> &arr, vector<vector<int>> &queries)
{
int n = arr.size();
// Allocate segment tree space
seg.resize(4 * n);
// Build tree initially
build(0, 0, n - 1, arr);
vector<long long> ans;
// Process all queries
for (auto &q : queries)
{
// Update query
if (q[0] == 1)
{
update(0, 0, n - 1, q[1], q[2]);
}
// Range query
else
{
ans.push_back(query(0, 0, n - 1, q[1], q[2]));
}
}
return ans;
}
};