Given an array arr[] consisting of N integers and an array Queries[][] with each query of the form {x, y}. For each query, the task is to replace the element at index x ( 1-based indexing ) by y and find the length of the longest subsequence having no similar adjacent elements.
Examples:
Input: arr[] = {1, 1, 2, 5, 2}, Q = 2, Queries[][] = {{1, 3}, {4, 2}}
Output: 5 3
Explanation:
Initially the array is {1, 1, 2, 5, 2}.
Query 1: Modifying the value at index 1 to 3, the array modifies to {3, 1, 2, 5, 2}.
Therefore, the longest subsequence having no similar adjacent elements is {3, 1, 2, 5, 2}, which is of length 5.
Therefore, print 5 as the answer.
Query 2: Modifying the value at index 4 to 2, the array modifies to {3, 1, 2, 2, 2}.
Now Therefore, the longest subsequence having no similar adjacent elements is {3, 1, 2}, which is of length 3.
Therefore, print 2 as the answer.Input: arr[] = {1, 1, 2, 5, 2}, Q = 1, Queries[][] = {{2, 2}}
Output: 4
Explanation:
Initially the array is {1, 1, 2, 5, 2}.
Query 1: Modifying the value at index 2 to 2, the array modified to {1, 2, 2, 5, 2}.
Therefore, the longest subsequence having no similar adjacent elements is {1, 2, 5, 2}, which is of length 4.
Therefore, print the value as 4.
Naive Approach: Follow the steps below to solve the problem using the simplest possible approach:
- Add the element to the subsequence only if it is not equal to the previous element of the subsequence.
- For each query {x, y}, replace the element at index x with y.
- Keep track of the longest subsequence found at any point by a variable count.
- Traverse through the array and increment count variable by 1 whenever the current element of the sequence is not equal to the previous element of the sequence.
- After iterating the sequence once, count contains the length of longest required subsequence.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find the length of the // longest subsequence such that no // two adjacent elements are equal void longestSubsequence( int N, int Q,
int arr[],
int Queries[][2])
{ for ( int i = 0; i < Q; i++) {
// Replace element at
// index x with y
int x = Queries[i][0];
int y = Queries[i][1];
// Since x is 1-indexed,
// decrement x by 1
arr[x - 1] = y;
// Keep track of number of
// elements in subsequence
int count = 1;
for ( int j = 1; j < N; j++) {
// If previous element is not
// same as current element
if (arr[j] != arr[j - 1]) {
count += 1;
}
}
// Print the desired count
cout << count << ' ' ;
}
} // Driver Code int main()
{ int arr[] = { 1, 1, 2, 5, 2 };
int N = sizeof (arr) / sizeof (arr[0]);
int Q = 2;
int Queries[Q][2] = { { 1, 3 }, { 4, 2 } };
// Function Call
longestSubsequence(N, Q, arr, Queries);
return 0;
} |
// Java program for the above approach import java.util.*;
class GFG
{ // Function to find the length of the // longest subsequence such that no // two adjacent elements are equal static void longestSubsequence( int N, int Q,
int arr[],
int Queries[][])
{ for ( int i = 0 ; i < Q; i++)
{
// Replace element at
// index x with y
int x = Queries[i][ 0 ];
int y = Queries[i][ 1 ];
// Since x is 1-indexed,
// decrement x by 1
arr[x - 1 ] = y;
// Keep track of number of
// elements in subsequence
int count = 1 ;
for ( int j = 1 ; j < N; j++)
{
// If previous element is not
// same as current element
if (arr[j] != arr[j - 1 ])
{
count += 1 ;
}
}
// Print the desired count
System.out.print(count + " " );
}
} // Driver Code public static void main(String[] args)
{ int arr[] = { 1 , 1 , 2 , 5 , 2 };
int N = arr.length;
int Q = 2 ;
int Queries[][] = { { 1 , 3 }, { 4 , 2 } };
// Function Call
longestSubsequence(N, Q, arr, Queries);
} } // This code is contributed by gauravrajput1 |
# Python3 program for the above approach # Function to find the length of the # longest subsequence such that no # two adjacent elements are equal def longestSubsequence(N, Q, arr, Queries):
for i in range (Q):
# Replace element at
# index x with y
x = Queries[i][ 0 ]
y = Queries[i][ 1 ]
# Since x is 1-indexed,
# decrement x by 1
arr[x - 1 ] = y
# Keep track of number of
# elements in subsequence
count = 1
for j in range ( 1 , N):
# If previous element is not
# same as current element
if (arr[j] ! = arr[j - 1 ]):
count + = 1
# Print the desired count
print (count, end = ' ' )
# Driver Code if __name__ = = "__main__" :
arr = [ 1 , 1 , 2 , 5 , 2 ]
N = len (arr)
Q = 2
Queries = [ [ 1 , 3 ], [ 4 , 2 ] ]
# Function Call
longestSubsequence(N, Q, arr, Queries)
# This code is contributed by chitranayal |
// C# program for // the above approach using System;
using System.Collections.Generic;
class GFG{
// Function to find the length of the // longest subsequence such that no // two adjacent elements are equal static void longestSubsequence( int N, int Q,
int []arr,
int [,]Queries)
{ for ( int i = 0; i < Q; i++)
{
// Replace element at
// index x with y
int x = Queries[i, 0];
int y = Queries[i, 1];
// Since x is 1-indexed,
// decrement x by 1
arr[x - 1] = y;
// Keep track of number of
// elements in subsequence
int count = 1;
for ( int j = 1; j < N; j++)
{
// If previous element is not
// same as current element
if (arr[j] != arr[j - 1])
{
count += 1;
}
}
// Print the desired count
Console.Write(count + " " );
}
} // Driver Code public static void Main(String[] args)
{ int []arr = { 1, 1, 2, 5, 2 };
int N = arr.Length;
int Q = 2;
int [,]Queries = { { 1, 3 }, { 4, 2 } };
// Function Call
longestSubsequence(N, Q, arr, Queries);
} } // This code is contributed by jana_sayantan |
<script> // JavaScript implementation of the above approach // Function to find the length of the // longest subsequence such that no // two adjacent elements are equal function longestSubsequence(N, Q,
arr, Queries)
{ for (let i = 0; i < Q; i++)
{
// Replace element at
// index x with y
let x = Queries[i][0];
let y = Queries[i][1];
// Since x is 1-indexed,
// decrement x by 1
arr[x - 1] = y;
// Keep track of number of
// elements in subsequence
let count = 1;
for (let j = 1; j < N; j++)
{
// If previous element is not
// same as current element
if (arr[j] != arr[j - 1])
{
count += 1;
}
}
// Print the desired count
document.write(count + " " );
}
} // Driver code let arr = [ 1, 1, 2, 5, 2 ];
let N = arr.length;
let Q = 2;
let Queries = [[ 1, 3 ], [ 4, 2 ]];
// Function Call
longestSubsequence(N, Q, arr, Queries);
// This code is contributed by code_hunt.
</script> |
5 3
Time Complexity: O(N*Q)
Auxiliary Space: O(N)
Efficient Approach: To optimize the above approach, an observation is found that the presence of an element in the required subsequence only depends on its previous element as shown below:
- Replacing the element at index x will only affect the contribution of elements at indices x and x + 1, in the final answer.
- Therefore, subtracting the contributions of these 2 indices from the variable count and recalculating contributions of these 2 indices will give the required answer in constant time.
Follow the steps below to solve the problem:
- Initialize a variable, say count, to store the count of subsequences.
- Traverse the given array and count those elements that are different from the previous element of the array and store it in a variable count.
- Now traverse each query {x, y} and perform the following:
- If the element at index (x – 1) is different from the element at index x, then decrement count by 1.
- If the element at index (x – 1) is different from the element y, then increment count by 1.
- Similarly, if the element at index (x + 1) is different from the element at index x, then decrement count by 1.
- If the element at index (x + 1) is different from the element y, then increment count by 1.
- Print the value of count after each query as the result.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
void longestSubsequence( int N, int Q,
int arr[],
int Queries[][2])
{ int count = 1;
// Traverse the array arr[]
for ( int i = 1; i < N; i++) {
// If previous element is not
// same as current element
if (arr[i] != arr[i - 1]) {
count += 1;
}
}
// Traverse the queries
for ( int i = 0; i < Q; i++) {
// Replace element at
// index x with y
int x = Queries[i][0];
int y = Queries[i][1];
// Recalculate for index x
if (x > 1) {
// Subtract contribution
// of element at index x
if (arr[x - 1] != arr[x - 2]) {
count -= 1;
}
// Add contribution of y
if (arr[x - 2] != y) {
count += 1;
}
}
// Recalculate for index x + 1
if (x < N) {
// Subtract contribution of
// element at index x + 1
if (arr[x] != arr[x - 1]) {
count -= 1;
}
// Adds contribution of y
if (y != arr[x]) {
count += 1;
}
}
cout << count << ' ' ;
// Replace the element
arr[x - 1] = y;
}
} // Driver Code int main()
{ int arr[] = { 1, 1, 2, 5, 2 };
int N = sizeof (arr) / sizeof (arr[0]);
int Q = 2;
int Queries[Q][2] = { { 1, 3 }, { 4, 2 } };
// Function Call
longestSubsequence(N, Q, arr, Queries);
return 0;
} |
// Java program for the above approach import java.util.*;
class GFG{
static void longestSubsequence( int N, int Q,
int arr[],
int Queries[][])
{ int count = 1 ;
// Traverse the array arr[]
for ( int i = 1 ; i < N; i++)
{
// If previous element is not
// same as current element
if (arr[i] != arr[i - 1 ])
{
count += 1 ;
}
}
// Traverse the queries
for ( int i = 0 ; i < Q; i++)
{
// Replace element at
// index x with y
int x = Queries[i][ 0 ];
int y = Queries[i][ 1 ];
// Recalculate for index x
if (x > 1 )
{
// Subtract contribution
// of element at index x
if (arr[x - 1 ] != arr[x - 2 ])
{
count -= 1 ;
}
// Add contribution of y
if (arr[x - 2 ] != y)
{
count += 1 ;
}
}
// Recalculate for index x + 1
if (x < N)
{
// Subtract contribution of
// element at index x + 1
if (arr[x] != arr[x - 1 ])
{
count -= 1 ;
}
// Adds contribution of y
if (y != arr[x])
{
count += 1 ;
}
}
System.out.print(count + " " );
// Replace the element
arr[x - 1 ] = y;
}
} // Driver Code public static void main(String args[])
{ int arr[] = { 1 , 1 , 2 , 5 , 2 };
int N = arr.length;
int Q = 2 ;
int Queries[][] = { { 1 , 3 }, { 4 , 2 } };
// Function Call
longestSubsequence(N, Q, arr, Queries);
} } // This code is contributed by jana_sayantan |
# Python3 program for the above approach def longestSubsequence(N, Q, arr, Queries):
count = 1
# Traverse the array arr[]
for i in range ( 1 , N):
# If previous element is not
# same as current element
if (arr[i] ! = arr[i - 1 ]):
count + = 1
# Traverse the queries
for i in range (Q):
# Replace element at
# index x with y
x = Queries[i][ 0 ]
y = Queries[i][ 1 ]
# Recalculate for index x
if (x > 1 ):
# Subtract contribution
# of element at index x
if (arr[x - 1 ] ! = arr[x - 2 ]):
count - = 1
# Add contribution of y
if (arr[x - 2 ] ! = y):
count + = 1
# Recalculate for index x + 1
if (x < N):
# Subtract contribution of
# element at index x + 1
if (arr[x] ! = arr[x - 1 ]):
count - = 1
# Adds contribution of y
if (y ! = arr[x]):
count + = 1
print (count, end = ' ' )
# Replace the element
arr[x - 1 ] = y
# Driver Code if __name__ = = "__main__" :
arr = [ 1 , 1 , 2 , 5 , 2 ]
N = len (arr)
Q = 2
Queries = [ [ 1 , 3 ], [ 4 , 2 ] ]
# Function Call
longestSubsequence(N, Q, arr, Queries)
# This code is contributed by AnkThon |
// C# program for the above approach using System;
class GFG{
static void longestSubsequence( int N, int Q,
int []arr,
int [,]Queries)
{ int count = 1;
// Traverse the array arr[]
for ( int i = 1; i < N; i++)
{
// If previous element is not
// same as current element
if (arr[i] != arr[i - 1])
{
count += 1;
}
}
// Traverse the queries
for ( int i = 0; i < Q; i++)
{
// Replace element at
// index x with y
int x = Queries[i, 0];
int y = Queries[i, 1];
// Recalculate for index x
if (x > 1)
{
// Subtract contribution
// of element at index x
if (arr[x - 1] != arr[x - 2])
{
count -= 1;
}
// Add contribution of y
if (arr[x - 2] != y)
{
count += 1;
}
}
// Recalculate for index x + 1
if (x < N)
{
// Subtract contribution of
// element at index x + 1
if (arr[x] != arr[x - 1])
{
count -= 1;
}
// Adds contribution of y
if (y != arr[x])
{
count += 1;
}
}
Console.Write(count + " " );
// Replace the element
arr[x - 1] = y;
}
} // Driver Code public static void Main( string []args)
{ int []arr = { 1, 1, 2, 5, 2 };
int N = arr.Length;
int Q = 2;
int [,]Queries = { { 1, 3 }, { 4, 2 } };
// Function Call
longestSubsequence(N, Q, arr, Queries);
} } // This code is contributed by AnkThon |
<script> // javascript program for the above approach function longestSubsequence( N , Q , arr , Queries) {
var count = 1;
// Traverse the array arr
for ( var i = 1; i < N; i++) {
// If previous element is not
// same as current element
if (arr[i] != arr[i - 1]) {
count += 1;
}
}
// Traverse the queries
for ( var i = 0; i < Q; i++) {
// Replace element at
// index x with y
var x = Queries[i][0];
var y = Queries[i][1];
// Recalculate for index x
if (x > 1) {
// Subtract contribution
// of element at index x
if (arr[x - 1] != arr[x - 2]) {
count -= 1;
}
// Add contribution of y
if (arr[x - 2] != y) {
count += 1;
}
}
// Recalculate for index x + 1
if (x < N) {
// Subtract contribution of
// element at index x + 1
if (arr[x] != arr[x - 1]) {
count -= 1;
}
// Adds contribution of y
if (y != arr[x]) {
count += 1;
}
}
document.write(count + " " );
// Replace the element
arr[x - 1] = y;
}
}
// Driver Code
var arr = [ 1, 1, 2, 5, 2 ];
var N = arr.length;
var Q = 2;
var Queries = [ [ 1, 3 ], [ 4, 2 ] ];
// Function Call
longestSubsequence(N, Q, arr, Queries);
// This code contributed by Princi Singh </script> |
5 3
Time Complexity: O(N + Q)
Auxiliary Space: O(N)