An Alternative Way
Description:â
You are given two arrays and , each of length . You are allowed to perform the following operation on array any number of times (including zero):
- Choose two indices and such that ;
- For each index from to (both inclusive),
- Set if is odd.
- Set if is even.
Determine whether you can make the array equal to the array by performing the operation any number of times.
Input The first line contains a single integer () â the number of test cases. The first line of each test case contains a single integer () â the length of the arrays. The second line contains integers . The third line contains integers .
Output For each test case, print "YES" if you can make array equal to array and "NO" otherwise.
Approaches:â
1. Prefix Sum Invariant (Optimal)â
Whenever an array operation involves alternating additions and subtractions (like ), it is highly recommended to look at how it affects the prefix sums of the array.
-
Analyzing the Operation's Effect: Let's see what happens to the prefix sums of when we apply an operation on .
- The sequence of changes to the elements is
- The prefix sums of this change sequence are always either or .
- This means that no matter what and we pick, we can never decrease any prefix sum of the array . We can only increase them or leave them unchanged.
-
Proving Independence: Can we increase a specific prefix sum without messing up the others? Yes!
- For any , choosing and adds to and to . This increases the prefix sum at index by exactly , and leaves all other prefix sums unchanged.
- For , choosing and adds to . This increases the total sum () by exactly , and leaves all other prefix sums unchanged.
-
Algorithm: Since we can independently increase any prefix sum, but we can never decrease any prefix sum, the only condition to transform into is that every prefix sum of must be greater than or equal to the corresponding prefix sum of . We just calculate a running sum for both arrays and check if
sumA <= sumBat every step.
Complexityâ
- Time Complexity: per testcase, where is the length of the arrays. We iterate through the arrays exactly once.
- Space Complexity: auxiliary space, as we only need two integer variables to keep track of the running prefix sums.
Solutions:â
C++â
#include <iostream>
#include <vector>
using namespace std;
void solve() {
int n;
cin >> n;
vector<long long> a(n), b(n);
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n; i++) cin >> b[i];
long long sumA = 0, sumB = 0;
bool possible = true;
for (int i = 0; i < n; i++) {
sumA += a[i];
sumB += b[i];
// The prefix sum of a can never exceed the prefix sum of b
if (sumA > sumB) {
possible = false;
break;
}
}
if (possible) {
cout << "YES\n";
} else {
cout << "NO\n";
}
}
int main() {
// Fast I/O
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
Javaâ
import java.util.Scanner;
public class Solution {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
if (scanner.hasNextInt()) {
int t = scanner.nextInt();
while (t-- > 0) {
solve(scanner);
}
}
scanner.close();
}
private static void solve(Scanner scanner) {
int n = scanner.nextInt();
long[] a = new long[n];
long[] b = new long[n];
for (int i = 0; i < n; i++) a[i] = scanner.nextLong();
for (int i = 0; i < n; i++) b[i] = scanner.nextLong();
long sumA = 0, sumB = 0;
boolean possible = true;
for (int i = 0; i < n; i++) {
sumA += a[i];
sumB += b[i];
if (sumA > sumB) {
possible = false;
}
}
if (possible) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
Pythonâ
import sys
def solve():
input_data = sys.stdin.read().split()
if not input_data:
return
t = int(input_data[0])
idx = 1
for _ in range(t):
n = int(input_data[idx])
idx += 1
a = list(map(int, input_data[idx : idx + n]))
idx += n
b = list(map(int, input_data[idx : idx + n]))
idx += n
sumA = 0
sumB = 0
possible = True
for i in range(n):
sumA += a[i]
sumB += b[i]
if sumA > sumB:
possible = False
break
if possible:
print("YES")
else:
print("NO")
if __name__ == "__main__":
solve()
JavaScriptâ
const fs = require('fs');
function main() {
const input = fs.readFileSync('/dev/stdin', 'utf-8').trim().split(/\s+/);
if (input.length === 0 || input[0] === '') return;
let t = parseInt(input[0], 10);
let idx = 1;
for (let i = 0; i < t; i++) {
let n = parseInt(input[idx++], 10);
let a = [];
for (let j = 0; j < n; j++) {
a.push(parseInt(input[idx++], 10));
}
let b = [];
for (let j = 0; j < n; j++) {
b.push(parseInt(input[idx++], 10));
}
let sumA = 0n; // Using BigInt for safety against large sums
let sumB = 0n;
let possible = true;
for (let j = 0; j < n; j++) {
sumA += BigInt(a[j]);
sumB += BigInt(b[j]);
if (sumA > sumB) {
possible = false;
break;
}
}
if (possible) {
console.log("YES");
} else {
console.log("NO");
}
}
}
main();
Completed working through this block? Sync progress to workspace.