给定大小为N的二进制数组arr [] 。任务是回答Q查询,该查询可以是以下任意一种:
类型1 – 1 lr:使用1对从l到r的所有数组元素执行按位异或运算。
类型2 – 2 lr:返回子数组[l,r]中值为1的两个元素之间的最小距离。
类型3 – 3 lr:返回子数组[l,r]中值为1的两个元素之间的最大距离。
类型4 – 4 lr:返回子数组[l,r]中值为0的两个元素之间的最小距离。
类型5 – 5 lr:返回子数组[l,r]中值为0的两个元素之间的最大距离。
例子:
Input : arr[] = {1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0}, q=5
Output : 2 2 3 2
Explanation :
query 1 : Type 2, l=3, r=7
Range 3 to 7 contains { 1, 0, 1, 0, 1 }.
So, the minimum distance between two elements with value 1 is 2.
query 2 : Type 3, l=2, r=5
Range 2 to 5 contains { 0, 1, 0, 1 }.
So, the maximum distance between two elements with value 1 is 2.
query 3 : Type 1, l=1, r=4
After update array becomes {1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0}
query 4 : Type 4, l=3, r=7
Range 3 to 7 in updated array contains { 0, 1, 1, 0, 1 }.
So, the minimum distance between two elements with value 0 is 3.
query 5 : Type 5, l=4, r=9
Range 4 to 9 contains { 1, 1, 0, 1, 0, 1 }.
So, the maximum distance between two elements with value 0 is 2.
方法:
我们将创建一个细分树,并使用具有延迟传播的范围更新来解决此问题。
- 段树中的每个节点将具有最左1以及最右1,最左0以及最右0的索引,以及包含子数组{l,r}中任何值为1的元素之间的最大和最小距离的整数作为子数组{l,r}中值为0的任何元素之间的最大和最小距离。
- 现在,在此段树中,我们可以按如下所示合并左右节点:
CPP
// l1 = leftmost index of 1, l0 = leftmost index of 0.
// r1 = rightmost index of 1, r0 = rightmost index of 0.
// max1 = maximum distance between two 1’s.
// max0 = maximum distance between two 0’s.
// min1 = minimum distance between two 1’s.
// min0 = minimum distance between two 0’s.
node Merge(node left, node right)
{
node cur;
if left.l0 is valid
cur.l0 = left.l0
else
cur.l0 = r.l0
// We will do this for all values
// i.e. cur.r0, cur.l1, cur.r1, cur.l0
// To find the min and max difference between two 1's and 0's
// we will take min/max value of left side, right side and
// difference between rightmost index of 1/0 in right node
// and leftmost index of 1/0 in left node respectively.
cur.min0 = minimum of left.min0 and right.min0
if left.r0 is valid and right.l0 is valid
cur.min0 = minimum of cur.min0 and (right.l0 - left.r0)
// We will do this for all max/min values
// i.e. cur.min0, cur.min1, cur.max1, cur.max0
return cur;
}
CPP
// C++ program for the given problem
#include
using namespace std;
int lazy[100001];
// Class for each node
// in the segment tree
class node {
public:
int l1, r1, l0, r0;
int min0, max0, min1, max1;
node()
{
l1 = r1 = l0 = r0 = -1;
max1 = max0 = INT_MIN;
min1 = min0 = INT_MAX;
}
} seg[100001];
// A utility function for
// merging two nodes
node MergeUtil(node l, node r)
{
node x;
x.l0 = (l.l0 != -1) ? l.l0 : r.l0;
x.r0 = (r.r0 != -1) ? r.r0 : l.r0;
x.l1 = (l.l1 != -1) ? l.l1 : r.l1;
x.r1 = (r.r1 != -1) ? r.r1 : l.r1;
x.min0 = min(l.min0, r.min0);
if (l.r0 != -1 && r.l0 != -1)
x.min0 = min(x.min0, r.l0 - l.r0);
x.min1 = min(l.min1, r.min1);
if (l.r1 != -1 && r.l1 != -1)
x.min1 = min(x.min1, r.l1 - l.r1);
x.max0 = max(l.max0, r.max0);
if (l.l0 != -1 && r.r0 != -1)
x.max0 = max(x.max0, r.r0 - l.l0);
x.max1 = max(l.max1, r.max1);
if (l.l1 != -1 && r.r1 != -1)
x.max1 = max(x.max1, r.r1 - l.l1);
return x;
}
// utility function
// for updating a node
node UpdateUtil(node x)
{
swap(x.l0, x.l1);
swap(x.r0, x.r1);
swap(x.min1, x.min0);
swap(x.max0, x.max1);
return x;
}
// A recursive function that constructs
// Segment Tree for given string
void Build(int qs, int qe, int ind, int arr[])
{
// If start is equal to end then
// insert the array element
if (qs == qe) {
if (arr[qs] == 1) {
seg[ind].l1 = seg[ind].r1 = qs;
}
else {
seg[ind].l0 = seg[ind].r0 = qs;
}
lazy[ind] = 0;
return;
}
int mid = (qs + qe) >> 1;
// Build the segment tree
// for range qs to mid
Build(qs, mid, ind << 1, arr);
// Build the segment tree
// for range mid+1 to qe
Build(mid + 1, qe, ind << 1 | 1, arr);
// merge the two child nodes
// to obtain the parent node
seg[ind] = MergeUtil(
seg[ind << 1],
seg[ind << 1 | 1]);
}
// Query in a range qs to qe
node Query(int qs, int qe,
int ns, int ne, int ind)
{
if (lazy[ind] != 0) {
seg[ind] = UpdateUtil(seg[ind]);
if (ns != ne) {
lazy[ind * 2] ^= lazy[ind];
lazy[ind * 2 + 1] ^= lazy[ind];
}
lazy[ind] = 0;
}
node x;
// If the range lies in this segment
if (qs <= ns && qe >= ne)
return seg[ind];
// If the range is out of the bounds
// of this segment
if (ne < qs || ns > qe || ns > ne)
return x;
// Else query for the right and left
// child node of this subtree
// and merge them
int mid = (ns + ne) >> 1;
node l = Query(qs, qe, ns,
mid, ind << 1);
node r = Query(qs, qe,
mid + 1, ne,
ind << 1 | 1);
x = MergeUtil(l, r);
return x;
}
// range update using lazy prpagation
void RangeUpdate(int us, int ue,
int ns, int ne, int ind)
{
if (lazy[ind] != 0) {
seg[ind] = UpdateUtil(seg[ind]);
if (ns != ne) {
lazy[ind * 2] ^= lazy[ind];
lazy[ind * 2 + 1] ^= lazy[ind];
}
lazy[ind] = 0;
}
// If the range is out of the bounds
// of this segment
if (ns > ne || ns > ue || ne < us)
return;
// If the range lies in this segment
if (ns >= us && ne <= ue) {
seg[ind] = UpdateUtil(seg[ind]);
if (ns != ne) {
lazy[ind * 2] ^= 1;
lazy[ind * 2 + 1] ^= 1;
}
return;
}
// Else query for the right and left
// child node of this subtree
// and merge them
int mid = (ns + ne) >> 1;
RangeUpdate(us, ue, ns, mid, ind << 1);
RangeUpdate(us, ue, mid + 1, ne, ind << 1 | 1);
node l = seg[ind << 1], r = seg[ind << 1 | 1];
seg[ind] = MergeUtil(l, r);
}
// Driver code
int main()
{
int arr[] = { 1, 1, 0,
1, 0, 1,
0, 1, 0,
1, 0, 1,
1, 0 };
int n = sizeof(arr) / sizeof(arr[0]);
// Build the segment tree
Build(0, n - 1, 1, arr);
// Query of Type 2 in the range 3 to 7
node ans = Query(3, 7, 0, n - 1, 1);
cout << ans.min1 << "\n";
// Query of Type 3 in the range 2 to 5
ans = Query(2, 5, 0, n - 1, 1);
cout << ans.max1 << "\n";
// Query of Type 1 in the range 1 to 4
RangeUpdate(1, 4, 0, n - 1, 1);
// Query of Type 4 in the range 3 to 7
ans = Query(3, 7, 0, n - 1, 1);
cout << ans.min0 << "\n";
// Query of Type 5 in the range 4 to 9
ans = Query(4, 9, 0, n - 1, 1);
cout << ans.max0 << "\n";
return 0;
}
Python3
# Python program for the given problem
from sys import maxsize
from typing import List
INT_MAX = maxsize
INT_MIN = -maxsize
lazy = [0 for _ in range(100001)]
# Class for each node
# in the segment tree
class node:
def __init__(self) -> None:
self.l1 = self.r1 = self.l0 = self.r0 = -1
self.max0 = self.max1 = INT_MIN
self.min0 = self.min1 = INT_MAX
seg = [node() for _ in range(100001)]
# A utility function for
# merging two nodes
def MergeUtil(l: node, r: node) -> node:
x = node()
x.l0 = l.l0 if (l.l0 != -1) else r.l0
x.r0 = r.r0 if (r.r0 != -1) else l.r0
x.l1 = l.l1 if (l.l1 != -1) else r.l1
x.r1 = r.r1 if (r.r1 != -1) else l.r1
x.min0 = min(l.min0, r.min0)
if (l.r0 != -1 and r.l0 != -1):
x.min0 = min(x.min0, r.l0 - l.r0)
x.min1 = min(l.min1, r.min1)
if (l.r1 != -1 and r.l1 != -1):
x.min1 = min(x.min1, r.l1 - l.r1)
x.max0 = max(l.max0, r.max0)
if (l.l0 != -1 and r.r0 != -1):
x.max0 = max(x.max0, r.r0 - l.l0)
x.max1 = max(l.max1, r.max1)
if (l.l1 != -1 and r.r1 != -1):
x.max1 = max(x.max1, r.r1 - l.l1)
return x
# utility function
# for updating a node
def UpdateUtil(x: node) -> node:
x.l0, x.l1 = x.l1, x.l0
x.r0, x.r1 = x.r1, x.r0
x.min1, x.min0 = x.min0, x.min1
x.max0, x.max1 = x.max1, x.max0
return x
# A recursive function that constructs
# Segment Tree for given string
def Build(qs: int, qe: int, ind: int, arr: List[int]) -> None:
# If start is equal to end then
# insert the array element
if (qs == qe):
if (arr[qs] == 1):
seg[ind].l1 = seg[ind].r1 = qs
else:
seg[ind].l0 = seg[ind].r0 = qs
lazy[ind] = 0
return
mid = (qs + qe) >> 1
# Build the segment tree
# for range qs to mid
Build(qs, mid, ind << 1, arr)
# Build the segment tree
# for range mid+1 to qe
Build(mid + 1, qe, ind << 1 | 1, arr)
# merge the two child nodes
# to obtain the parent node
seg[ind] = MergeUtil(seg[ind << 1], seg[ind << 1 | 1])
# Query in a range qs to qe
def Query(qs: int, qe: int, ns: int, ne: int, ind: int) -> node:
if (lazy[ind] != 0):
seg[ind] = UpdateUtil(seg[ind])
if (ns != ne):
lazy[ind * 2] ^= lazy[ind]
lazy[ind * 2 + 1] ^= lazy[ind]
lazy[ind] = 0
x = node()
# If the range lies in this segment
if (qs <= ns and qe >= ne):
return seg[ind]
# If the range is out of the bounds
# of this segment
if (ne < qs or ns > qe or ns > ne):
return x
# Else query for the right and left
# child node of this subtree
# and merge them
mid = (ns + ne) >> 1
l = Query(qs, qe, ns, mid, ind << 1)
r = Query(qs, qe, mid + 1, ne, ind << 1 | 1)
x = MergeUtil(l, r)
return x
# range update using lazy prpagation
def RangeUpdate(us: int, ue: int, ns: int, ne: int, ind: int) -> None:
if (lazy[ind] != 0):
seg[ind] = UpdateUtil(seg[ind])
if (ns != ne):
lazy[ind * 2] ^= lazy[ind]
lazy[ind * 2 + 1] ^= lazy[ind]
lazy[ind] = 0
# If the range is out of the bounds
# of this segment
if (ns > ne or ns > ue or ne < us):
return
# If the range lies in this segment
if (ns >= us and ne <= ue):
seg[ind] = UpdateUtil(seg[ind])
if (ns != ne):
lazy[ind * 2] ^= 1
lazy[ind * 2 + 1] ^= 1
return
# Else query for the right and left
# child node of this subtree
# and merge them
mid = (ns + ne) >> 1
RangeUpdate(us, ue, ns, mid, ind << 1)
RangeUpdate(us, ue, mid + 1, ne, ind << 1 | 1)
l = seg[ind << 1]
r = seg[ind << 1 | 1]
seg[ind] = MergeUtil(l, r)
# Driver code
if __name__ == "__main__":
arr = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0]
n = len(arr)
# Build the segment tree
Build(0, n - 1, 1, arr)
# Query of Type 2 in the range 3 to 7
ans = Query(3, 7, 0, n - 1, 1)
print(ans.min1)
# Query of Type 3 in the range 2 to 5
ans = Query(2, 5, 0, n - 1, 1)
print(ans.max1)
# Query of Type 1 in the range 1 to 4
RangeUpdate(1, 4, 0, n - 1, 1)
# Query of Type 4 in the range 3 to 7
ans = Query(3, 7, 0, n - 1, 1)
print(ans.min0)
# Query of Type 5 in the range 4 to 9
ans = Query(4, 9, 0, n - 1, 1)
print(ans.max0)
# This code is contributed by sanjeev2552
- 为了处理范围更新查询,我们将使用延迟传播。更新查询要求我们将l到r范围内的所有元素与1进行异或运算,从观察值中我们知道:
0 xor 1 = 1
1 xor 1 = 0
- 因此,我们可以观察到,在此更新之后,所有0都将变为1,而所有1都将变为0。因此,在我们的段树节点中,0和1的所有对应值也将被交换,即
l0 and l1 will get swapped
r0 and r1 will get swapped
min0 and min1 will get swapped
max0 and max1 will get swapped
- 然后,最后要找到任务2、3、4和5的答案,我们只需要调用给定范围{l,r}的查询函数,而我要找到任务1的答案,我们需要调用范围更新函数。
下面是上述方法的实现:
CPP
// C++ program for the given problem
#include
using namespace std;
int lazy[100001];
// Class for each node
// in the segment tree
class node {
public:
int l1, r1, l0, r0;
int min0, max0, min1, max1;
node()
{
l1 = r1 = l0 = r0 = -1;
max1 = max0 = INT_MIN;
min1 = min0 = INT_MAX;
}
} seg[100001];
// A utility function for
// merging two nodes
node MergeUtil(node l, node r)
{
node x;
x.l0 = (l.l0 != -1) ? l.l0 : r.l0;
x.r0 = (r.r0 != -1) ? r.r0 : l.r0;
x.l1 = (l.l1 != -1) ? l.l1 : r.l1;
x.r1 = (r.r1 != -1) ? r.r1 : l.r1;
x.min0 = min(l.min0, r.min0);
if (l.r0 != -1 && r.l0 != -1)
x.min0 = min(x.min0, r.l0 - l.r0);
x.min1 = min(l.min1, r.min1);
if (l.r1 != -1 && r.l1 != -1)
x.min1 = min(x.min1, r.l1 - l.r1);
x.max0 = max(l.max0, r.max0);
if (l.l0 != -1 && r.r0 != -1)
x.max0 = max(x.max0, r.r0 - l.l0);
x.max1 = max(l.max1, r.max1);
if (l.l1 != -1 && r.r1 != -1)
x.max1 = max(x.max1, r.r1 - l.l1);
return x;
}
// utility function
// for updating a node
node UpdateUtil(node x)
{
swap(x.l0, x.l1);
swap(x.r0, x.r1);
swap(x.min1, x.min0);
swap(x.max0, x.max1);
return x;
}
// A recursive function that constructs
// Segment Tree for given string
void Build(int qs, int qe, int ind, int arr[])
{
// If start is equal to end then
// insert the array element
if (qs == qe) {
if (arr[qs] == 1) {
seg[ind].l1 = seg[ind].r1 = qs;
}
else {
seg[ind].l0 = seg[ind].r0 = qs;
}
lazy[ind] = 0;
return;
}
int mid = (qs + qe) >> 1;
// Build the segment tree
// for range qs to mid
Build(qs, mid, ind << 1, arr);
// Build the segment tree
// for range mid+1 to qe
Build(mid + 1, qe, ind << 1 | 1, arr);
// merge the two child nodes
// to obtain the parent node
seg[ind] = MergeUtil(
seg[ind << 1],
seg[ind << 1 | 1]);
}
// Query in a range qs to qe
node Query(int qs, int qe,
int ns, int ne, int ind)
{
if (lazy[ind] != 0) {
seg[ind] = UpdateUtil(seg[ind]);
if (ns != ne) {
lazy[ind * 2] ^= lazy[ind];
lazy[ind * 2 + 1] ^= lazy[ind];
}
lazy[ind] = 0;
}
node x;
// If the range lies in this segment
if (qs <= ns && qe >= ne)
return seg[ind];
// If the range is out of the bounds
// of this segment
if (ne < qs || ns > qe || ns > ne)
return x;
// Else query for the right and left
// child node of this subtree
// and merge them
int mid = (ns + ne) >> 1;
node l = Query(qs, qe, ns,
mid, ind << 1);
node r = Query(qs, qe,
mid + 1, ne,
ind << 1 | 1);
x = MergeUtil(l, r);
return x;
}
// range update using lazy prpagation
void RangeUpdate(int us, int ue,
int ns, int ne, int ind)
{
if (lazy[ind] != 0) {
seg[ind] = UpdateUtil(seg[ind]);
if (ns != ne) {
lazy[ind * 2] ^= lazy[ind];
lazy[ind * 2 + 1] ^= lazy[ind];
}
lazy[ind] = 0;
}
// If the range is out of the bounds
// of this segment
if (ns > ne || ns > ue || ne < us)
return;
// If the range lies in this segment
if (ns >= us && ne <= ue) {
seg[ind] = UpdateUtil(seg[ind]);
if (ns != ne) {
lazy[ind * 2] ^= 1;
lazy[ind * 2 + 1] ^= 1;
}
return;
}
// Else query for the right and left
// child node of this subtree
// and merge them
int mid = (ns + ne) >> 1;
RangeUpdate(us, ue, ns, mid, ind << 1);
RangeUpdate(us, ue, mid + 1, ne, ind << 1 | 1);
node l = seg[ind << 1], r = seg[ind << 1 | 1];
seg[ind] = MergeUtil(l, r);
}
// Driver code
int main()
{
int arr[] = { 1, 1, 0,
1, 0, 1,
0, 1, 0,
1, 0, 1,
1, 0 };
int n = sizeof(arr) / sizeof(arr[0]);
// Build the segment tree
Build(0, n - 1, 1, arr);
// Query of Type 2 in the range 3 to 7
node ans = Query(3, 7, 0, n - 1, 1);
cout << ans.min1 << "\n";
// Query of Type 3 in the range 2 to 5
ans = Query(2, 5, 0, n - 1, 1);
cout << ans.max1 << "\n";
// Query of Type 1 in the range 1 to 4
RangeUpdate(1, 4, 0, n - 1, 1);
// Query of Type 4 in the range 3 to 7
ans = Query(3, 7, 0, n - 1, 1);
cout << ans.min0 << "\n";
// Query of Type 5 in the range 4 to 9
ans = Query(4, 9, 0, n - 1, 1);
cout << ans.max0 << "\n";
return 0;
}
Python3
# Python program for the given problem
from sys import maxsize
from typing import List
INT_MAX = maxsize
INT_MIN = -maxsize
lazy = [0 for _ in range(100001)]
# Class for each node
# in the segment tree
class node:
def __init__(self) -> None:
self.l1 = self.r1 = self.l0 = self.r0 = -1
self.max0 = self.max1 = INT_MIN
self.min0 = self.min1 = INT_MAX
seg = [node() for _ in range(100001)]
# A utility function for
# merging two nodes
def MergeUtil(l: node, r: node) -> node:
x = node()
x.l0 = l.l0 if (l.l0 != -1) else r.l0
x.r0 = r.r0 if (r.r0 != -1) else l.r0
x.l1 = l.l1 if (l.l1 != -1) else r.l1
x.r1 = r.r1 if (r.r1 != -1) else l.r1
x.min0 = min(l.min0, r.min0)
if (l.r0 != -1 and r.l0 != -1):
x.min0 = min(x.min0, r.l0 - l.r0)
x.min1 = min(l.min1, r.min1)
if (l.r1 != -1 and r.l1 != -1):
x.min1 = min(x.min1, r.l1 - l.r1)
x.max0 = max(l.max0, r.max0)
if (l.l0 != -1 and r.r0 != -1):
x.max0 = max(x.max0, r.r0 - l.l0)
x.max1 = max(l.max1, r.max1)
if (l.l1 != -1 and r.r1 != -1):
x.max1 = max(x.max1, r.r1 - l.l1)
return x
# utility function
# for updating a node
def UpdateUtil(x: node) -> node:
x.l0, x.l1 = x.l1, x.l0
x.r0, x.r1 = x.r1, x.r0
x.min1, x.min0 = x.min0, x.min1
x.max0, x.max1 = x.max1, x.max0
return x
# A recursive function that constructs
# Segment Tree for given string
def Build(qs: int, qe: int, ind: int, arr: List[int]) -> None:
# If start is equal to end then
# insert the array element
if (qs == qe):
if (arr[qs] == 1):
seg[ind].l1 = seg[ind].r1 = qs
else:
seg[ind].l0 = seg[ind].r0 = qs
lazy[ind] = 0
return
mid = (qs + qe) >> 1
# Build the segment tree
# for range qs to mid
Build(qs, mid, ind << 1, arr)
# Build the segment tree
# for range mid+1 to qe
Build(mid + 1, qe, ind << 1 | 1, arr)
# merge the two child nodes
# to obtain the parent node
seg[ind] = MergeUtil(seg[ind << 1], seg[ind << 1 | 1])
# Query in a range qs to qe
def Query(qs: int, qe: int, ns: int, ne: int, ind: int) -> node:
if (lazy[ind] != 0):
seg[ind] = UpdateUtil(seg[ind])
if (ns != ne):
lazy[ind * 2] ^= lazy[ind]
lazy[ind * 2 + 1] ^= lazy[ind]
lazy[ind] = 0
x = node()
# If the range lies in this segment
if (qs <= ns and qe >= ne):
return seg[ind]
# If the range is out of the bounds
# of this segment
if (ne < qs or ns > qe or ns > ne):
return x
# Else query for the right and left
# child node of this subtree
# and merge them
mid = (ns + ne) >> 1
l = Query(qs, qe, ns, mid, ind << 1)
r = Query(qs, qe, mid + 1, ne, ind << 1 | 1)
x = MergeUtil(l, r)
return x
# range update using lazy prpagation
def RangeUpdate(us: int, ue: int, ns: int, ne: int, ind: int) -> None:
if (lazy[ind] != 0):
seg[ind] = UpdateUtil(seg[ind])
if (ns != ne):
lazy[ind * 2] ^= lazy[ind]
lazy[ind * 2 + 1] ^= lazy[ind]
lazy[ind] = 0
# If the range is out of the bounds
# of this segment
if (ns > ne or ns > ue or ne < us):
return
# If the range lies in this segment
if (ns >= us and ne <= ue):
seg[ind] = UpdateUtil(seg[ind])
if (ns != ne):
lazy[ind * 2] ^= 1
lazy[ind * 2 + 1] ^= 1
return
# Else query for the right and left
# child node of this subtree
# and merge them
mid = (ns + ne) >> 1
RangeUpdate(us, ue, ns, mid, ind << 1)
RangeUpdate(us, ue, mid + 1, ne, ind << 1 | 1)
l = seg[ind << 1]
r = seg[ind << 1 | 1]
seg[ind] = MergeUtil(l, r)
# Driver code
if __name__ == "__main__":
arr = [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0]
n = len(arr)
# Build the segment tree
Build(0, n - 1, 1, arr)
# Query of Type 2 in the range 3 to 7
ans = Query(3, 7, 0, n - 1, 1)
print(ans.min1)
# Query of Type 3 in the range 2 to 5
ans = Query(2, 5, 0, n - 1, 1)
print(ans.max1)
# Query of Type 1 in the range 1 to 4
RangeUpdate(1, 4, 0, n - 1, 1)
# Query of Type 4 in the range 3 to 7
ans = Query(3, 7, 0, n - 1, 1)
print(ans.min0)
# Query of Type 5 in the range 4 to 9
ans = Query(4, 9, 0, n - 1, 1)
print(ans.max0)
# This code is contributed by sanjeev2552
2
2
3
2