Optimizing Array Operations for GCD and Median Calculations

GCD Optimization in Array Processing

When working with arrays, selecting the minimum element first often leads to optimal solutions for GCD-based problems. Consider an array where each element's GCD with previous selections contributes to the total sum. The optimal approach involves:

  1. Sorting the array and selecting the smallest element first
  2. Calculating GCDs with subsequent elements while maintaining the running GCD
  3. Accumulating the sum of these GCD values
int computeOptimalGCDSum(vector<int>& arr) {
    sort(arr.begin(), arr.end());
    int current_gcd = 0, total = 0;
    vector<bool> processed(arr.size(), false);
    
    for (int i = 0; i < arr.size(); ++i) {
        int min_gcd = INT_MAX, min_idx = -1;
        
        for (int j = 0; j < arr.size(); ++j) {
            if (!processed[j]) {
                int temp_gcd = gcd(current_gcd, arr[j]);
                if (temp_gcd < min_gcd) {
                    min_gcd = temp_gcd;
                    min_idx = j;
                }
            }
        }
        
        if (min_gcd == current_gcd) {
            total += (arr.size() - i) * current_gcd;
            break;
        }
        
        processed[min_idx] = true;
        current_gcd = min_gcd;
        total += current_gcd;
    }
    return total;
}

Median Calculation with Binary Search

For finding medians in segmented arrays, a binary search approach proves efficient:

  1. Preprocess the array with prefix sums
  2. For each query, binary search the median value
  3. Verify the median by checking segment counts
bool verifyMedian(const vector<int>& prefix, int x, int m, int n) {
    int count = 0;
    for (int k = 0; k * x <= n; ++k) {
        int lower = k * x;
        int upper = min(k * x + m, n);
        count += (k == 0) ? prefix[upper] : prefix[upper] - prefix[lower - 1];
    }
    return count >= (n + 1) / 2;
}

int findMedian(const vector<int>& arr, int x) {
    vector<int> prefix(arr.size() + 1, 0);
    for (int i = 1; i <= arr.size(); ++i) {
        prefix[i] = prefix[i - 1] + (arr[i - 1] <= i);
    }
    
    int left = 0, right = x;
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (verifyMedian(prefix, x, mid, arr.size())) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    return left;
}

Tree DP for Maximum Value Selection

In tree structures, dynamic programming helps maximize selected values while considering constraints:

struct TreeNode {
    int value;
    int cost;
    vector<TreeNode*> children;
};

pair<int, int> treeMaxSelection(TreeNode* node) {
    if (!node) return {0, 0};
    
    int select = node->value;
    int not_select = 0;
    
    for (auto child : node->children) {
        auto [child_select, child_not_select] = treeMaxSelection(child);
        not_select += max(child_select, child_not_select);
        select += max(child_select - 2 * node->cost, child_not_select);
    }
    
    return {select, not_select};
}

Tags: algorithm Optimization gcd binary-search dynamic-programming

Posted on Wed, 02 Sep 2026 16:18:34 +0000 by Delaran