1. Abridged Problem Statement  
Given two equal-length strings A and B of ‘+’ and ‘–’ characters, you may swap only adjacent opposite characters (i.e. “+-” ↔ “-+”). Determine if A can be transformed into B by such swaps, and if so, output the minimum number of swaps required; otherwise output –1.

2. Detailed Editorial  
Let n be the length of the strings. A swap exchanges a ‘+’ and a ‘–’ that are next to each other. Note that:  
- The relative order of all ‘+’s among themselves never changes (they’re indistinguishable, but you cannot swap two ‘+’s directly), and likewise for all ‘–’s.  
- Therefore, it is possible to reach string B from A if and only if A and B have the same count of ‘+’s (and hence the same count of ‘–’s). If counts differ, answer is –1.  

If the counts match, label each ‘+’ in A by its occurrence index (1st plus, 2nd plus, …) and likewise for each ‘–’. Do the same for B. Now each character in A has a unique target position in B. Build an array P of length n so that P[i] = target index in B of the character originally at A[i]. To transform A into B by adjacent opposite-character swaps is equivalent to sorting the permutation P via adjacent swaps (each swap of neighboring entries in P corresponds to swapping a ‘+’ and ‘–’ in A). The minimum number of adjacent swaps needed to sort P is exactly the inversion count of P.  

We can compute inversion count in O(n log n) by a classic merge sort–based algorithm. Overall time is O(n log n), memory O(n), which is fine for n up to 5000.

3. Provided C++ Solution with Detailed Comments  
```cpp
#include <bits/stdc++.h>
using namespace std;

// Overload << for pair to ease printing (not actually used in solve)
template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

// Overload >> for pair (not used)
template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

// Overload >> to read a vector of T
template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
}

// Overload << to print a vector of T
template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
}

string a, b;  // input strings

// Read input strings a and b
void read() {
    cin >> a >> b;
}

// For a string s, return two vectors: positions of '+' and positions of '-'
pair<vector<int>, vector<int>> get_pos_plus_minus(const string& s) {
    vector<int> pos, neg;
    for(int i = 0; i < (int)s.size(); i++) {
        if(s[i] == '+') {
            pos.push_back(i);
        } else {
            neg.push_back(i);
        }
    }
    return {pos, neg};
}

// Count inversions in array a using merge sort in O(n log n)
int64_t count_inversions(vector<int> a) {
    // Recursive lambda for merge sort + inversion counting
    function<int64_t(vector<int>&, int, int)> merge_sort =
        [&](vector<int>& a, int l, int r) -> int64_t {
        if(l == r) return 0;           // single element: no inversions
        int m = (l + r) / 2;
        // Count inversions in left and right halves
        int64_t ans = merge_sort(a, l, m) + merge_sort(a, m + 1, r);
        vector<int> temp;
        int i = l, j = m + 1;
        // Merge two sorted halves, counting cross-inversions
        while(i <= m && j <= r) {
            if(a[i] <= a[j]) {
                temp.push_back(a[i++]);
            } else {
                temp.push_back(a[j++]);
                ans += m - i + 1;  // all remaining in left half invert with a[j]
            }
        }
        // Copy any leftovers
        while(i <= m) temp.push_back(a[i++]);
        while(j <= r) temp.push_back(a[j++]);
        // Write back merged range into a
        for(int k = l; k <= r; k++) {
            a[k] = temp[k - l];
        }
        return ans;
    };

    return merge_sort(a, 0, (int)a.size() - 1);
}

void solve() {
    // Get positions of plus/minus in a and b
    auto [pos_a, neg_a] = get_pos_plus_minus(a);
    auto [pos_b, neg_b] = get_pos_plus_minus(b);

    // If counts differ, impossible
    if(pos_a.size() != pos_b.size() || neg_a.size() != neg_b.size()) {
        cout << -1 << '\n';
        return;
    }

    // We want to match the i-th plus in a to the i-th plus in b, etc.
    // We'll pop from back of pos_b and neg_b to assign targets in order of scanning a.
    reverse(pos_b.begin(), pos_b.end());
    reverse(neg_b.begin(), neg_b.end());

    vector<int> perm;  // perm[i] = target index in b of element a[i]
    perm.reserve(a.size());
    for(int i = 0; i < (int)a.size(); i++) {
        if(a[i] == '+') {
            // take next plus position in b
            perm.push_back(pos_b.back());
            pos_b.pop_back();
        } else {
            // take next minus position in b
            perm.push_back(neg_b.back());
            neg_b.pop_back();
        }
    }

    // The answer is the inversion count of this permutation
    cout << count_inversions(perm) << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    read();
    solve();
    return 0;
}
```

4. Python Solution with Detailed Comments  
```python
import sys
sys.setrecursionlimit(10000)

def read_input():
    """Reads two lines from stdin: strings a and b."""
    a = sys.stdin.readline().strip()
    b = sys.stdin.readline().strip()
    return a, b

def get_positions(s):
    """
    Returns two lists:
    - pos: all indices where s[i] == '+'
    - neg: all indices where s[i] == '-'
    """
    pos, neg = [], []
    for i, ch in enumerate(s):
        if ch == '+':
            pos.append(i)
        else:
            neg.append(i)
    return pos, neg

def count_inversions(arr):
    """
    Counts inversions in arr using a merge sort variant in O(n log n).
    Returns the inversion count.
    """
    def merge_sort(a, l, r):
        if l >= r:
            return 0
        m = (l + r) // 2
        inv = merge_sort(a, l, m) + merge_sort(a, m+1, r)
        temp = []
        i, j = l, m+1
        while i <= m and j <= r:
            if a[i] <= a[j]:
                temp.append(a[i])
                i += 1
            else:
                temp.append(a[j])
                j += 1
                inv += (m - i + 1)
        # collect remains
        while i <= m:
            temp.append(a[i]); i += 1
        while j <= r:
            temp.append(a[j]); j += 1
        # write back
        for k in range(l, r+1):
            a[k] = temp[k-l]
        return inv

    # Work on a copy so as not to destroy original
    return merge_sort(list(arr), 0, len(arr)-1)

def main():
    a, b = read_input()
    # Get plus/minus positions in both strings
    pos_a, neg_a = get_positions(a)
    pos_b, neg_b = get_positions(b)

    # If counts differ, impossible
    if len(pos_a) != len(pos_b) or len(neg_a) != len(neg_b):
        print(-1)
        return

    # We want to map the ith '+' in a to the ith '+' in b, etc.
    # We'll reverse the target lists to pop from the end efficiently.
    pos_b.reverse()
    neg_b.reverse()

    # Build the permutation: for each character in a, record its target index in b
    perm = []
    for ch in a:
        if ch == '+':
            perm.append(pos_b.pop())
        else:
            perm.append(neg_b.pop())

    # Answer: inversion count of this perm
    print(count_inversions(perm))

if __name__ == "__main__":
    main()
```

5. Compressed Editorial  
- Check that A and B have the same counts of ‘+’ and ‘–’; otherwise answer is –1.  
- Label each ‘+’ and ‘–’ in A and B by their occurrence order.  
- Build an array P where P[i] is the target index in B of the character at A[i].  
- The minimum adjacent opposite-character swaps equals the inversion count of P, computable in O(n log n).