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. C++ Solution
```cpp
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

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

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

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

string a, b;

void read() { cin >> a >> b; }

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};
}

int64_t count_inversions(vector<int> a) {
    function<int64_t(vector<int>&, int, int)> merge_sort = [&](vector<int>& a,
                                                               int l, int r) {
        if(l == r) {
            return 0LL;
        }
        int m = (l + r) / 2;
        int64_t ans = merge_sort(a, l, m) + merge_sort(a, m + 1, r);
        vector<int> b;
        int i = l, j = m + 1;
        while(i <= m && j <= r) {
            if(a[i] <= a[j]) {
                b.push_back(a[i++]);
            } else {
                b.push_back(a[j++]);
                ans += m - i + 1;
            }
        }
        while(i <= m) {
            b.push_back(a[i++]);
        }
        while(j <= r) {
            b.push_back(a[j++]);
        }
        for(int i = l; i <= r; i++) {
            a[i] = b[i - l];
        }
        return ans;
    };

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

void solve() {
    // Adjacent swaps of unlike particles preserve the relative order of the
    // '+' particles among themselves and of the '-' particles among
    // themselves, so a transformation exists only if both strings have the
    // same count of each sign. When it does, the i-th '+' of a must become the
    // i-th '+' of b (likewise for '-'). Build the target permutation perm:
    // perm[i] is the final position (index in b) of the particle at position i
    // in a. The minimum number of adjacent swaps equals the number of
    // inversions of perm, counted with a merge sort.

    auto [pos_a, neg_a] = get_pos_plus_minus(a);
    auto [pos_b, neg_b] = get_pos_plus_minus(b);

    if(pos_a.size() != pos_b.size() || neg_a.size() != neg_b.size()) {
        cout << -1 << '\n';
        return;
    }

    reverse(pos_b.begin(), pos_b.end());
    reverse(neg_b.begin(), neg_b.end());
    vector<int> perm;
    for(int i = 0; i < (int)a.size(); i++) {
        if(a[i] == '+') {
            perm.push_back(pos_b.back());
            pos_b.pop_back();
        } else {
            perm.push_back(neg_b.back());
            neg_b.pop_back();
        }
    }

    cout << count_inversions(perm) << '\n';
}

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

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        // cout << "Case #" << test << ": ";
        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).