SyntaxHighlighter

Sunday 3 August 2014

Длина объединения отрезков

На прямой заданы отрезки координатами левого и правого конца. Необходимо найти длину их объединения. Поместим все координаты в отдельный массив, при этом левому концу сопоставим -1, а правому +1. Все прямая разобъется на подотрезки, внутри которых нет других точек. Для каждого такого отрезка нужно определить надо ли добавлять его длину в общую сумму. Легко заметить что если количество левых концов слева от данной области равно количеству правых, то эта область не покрыта ни одним исходным отрезком, поэтому ее длину не надо добавлять. Для выяснения этого факта будем поддерживать переменную - баланс левых и правых концов.

template<typename T>
T segments_union(vector<pair<T, T>> s) {
    vector<pair<T, int> > v;
    for (int i = 0; i < sz(s); ++i) {
        v.pb(mp(s[i].first, -1));
        v.pb(mp(s[i].second, 1));
    }
    sort(all(v));
    T res = 0;
    for (int i = 0, sum = 0; i < sz(v); ++i) {
        if (sum) {
            res += v[i].first - v[i - 1].first;
        }
        sum += v[i].second;
    }
    return res;
}