Submission #507028

#TimeUsernameProblemLanguageResultExecution timeMemory
507028Aldas25Palembang Bridges (APIO15_bridge)C++14
22 / 100
340 ms33344 KiB
#include <bits/stdc++.h>

using namespace std;

#define FAST_IO ios_base::sync_with_stdio(0); cin.tie(nullptr)
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define REP(n) FOR(O, 1, (n))
#define pb push_back
#define f first
#define s second
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vii;

const int MAXN = 500100;
const ll INF = (ll)1e17;

int k, nn, n;
ll s[MAXN], t[MAXN];
vl pts;
set<ll> tmp;
map<ll, int> toId;
ll ans;
vector<pair<ll, int>> sortedS, sortedT, sortedST;

ll closed[MAXN], notOpened[MAXN];

void preCalc () {

    /// compression of points
    FOR(i, 1, n) {
        tmp.insert(s[i]);
        tmp.insert(t[i]);
    }

    ll id = 0;
    for (ll x : tmp) {
        pts.pb(x);
        toId[x] = id;
        id++;
    }

    /// sortedS and sortedT
    FOR(i, 1, n) {
        sortedS.pb({s[i], i});
        sortedT.pb({t[i], i});
        sortedST.pb({s[i] + t[i], i});
    }
    sort(sortedS.begin(), sortedS.end());
    sort(sortedT.begin(), sortedT.end());
    sort(sortedST.begin(), sortedST.end());

    /// closed and notOpen calc
    notOpened[0] = n;

    FOR(i, 1, n) {
        notOpened[toId[s[i]]]--;
        closed[toId[t[i]]]++;
    }

    FOR(i, 1, (int)pts.size()-1) {
        notOpened[i] += notOpened[i-1];
        closed[i] += closed[i-1];
    }
}

void solve1 () {
    //ll curMin = INF;
    ll cur = 0;

    int ch = 0;
    FOR(i, 0, (int)pts.size()-1) {
        if (closed[i] >= notOpened[i]) {
            ch = pts[i];
            break;
        }
    }

    FOR(i, 1, n) {
        cur += abs(s[i] - ch) + abs(t[i] - ch);
    }

    ans += cur;
    cout << ans << "\n";
}

void solve2 () {
    ll cur = 0;
    ll minCur = INF;

    FOR(aa, 0, (int)pts.size()-2) {
        ll b1 = pts[aa];
        ll b2 = pts[aa+1];
        cur = 0;
        FOR(i, 1, n) {
            ll cr1 = abs(s[i] - b1) + abs(t[i] - b1);
            ll cr2 = abs(s[i] - b2) + abs(t[i] - b2);
            cur += min(cr1, cr2);
        }
        minCur = min(minCur, cur);

        //cout << " b1 = " << b1 << "  b2 = " << b2 << " cur = " << cur << endl;

        int idS = 0, idT = 0, idST = 0;
        int cl = 0, notOp = n;

        while (idS < n && sortedS[idS].f <= b2) {
            idS++;
            notOp--;
        }
        while (idT < n && sortedT[idT].f <= b2) {
            int id = sortedT[idT].s;
            if (s[id] > b1)
                cl++;
            idT++;
            //cl++;
        }
        while (idST < n && sortedST[idST].f <= b1+b2) {
            int id = sortedST[idST].s;
            if (s[id] > b1)
                cl--;
            idST++;
            //cl--;
        }

        FOR(bb, aa+2, (int)pts.size()-1) {
            b2 = pts[bb];

            ll d = b2 - pts[bb-1];
            //cout << "    d = " <<d << "  cl = " << cl << " notOp = " << notOp << endl;
            cur += d * 2 * (cl - notOp);

            while (idS < n && sortedS[idS].f <= b2) {
                idS++;
                notOp--;
            }
            while (idT < n && sortedT[idT].f <= b2) {
                int id = sortedT[idT].s;
                if (s[id] > b1)
                    cl++;

                idT++;
                //cl++;
            }
            while (idST < n && sortedST[idST].f <= b1+b2) {
                int id = sortedST[idST].s;
                if (s[id] > b1) {
                    cur -= abs(b2 - s[id]) + abs(b2 - t[id]);
                    cur += abs(s[id] - b1) + abs(t[id] - b1);
                    cl--;
                }

                idST++;
                //cl--;
            }

            //cout << " b1 = " << b1 << "  b2 = " << b2 << " cur = " << cur << endl;

            minCur = min(minCur, cur);
        }
    }

    ans += minCur;
    //cout << " minCur = " << minCur << endl;
    cout << ans << "\n";
}

int main()
{
    FAST_IO;

    cin >> k >> nn;

    FOR(i, 1, nn) {
        char pp, qq;
        ll ss, tt;
        cin >> pp >> ss >> qq >> tt;
        if (pp == qq) {
            ans += abs(ss-tt);
        } else {
            n++;
            ans++;
            //ans += abs(ss-tt);
            s[n] = min(ss,tt);
            t[n] = max(ss,tt);
        }
    }
    //cout << " ans = " << ans << endl;

    preCalc();

    if (k == 1) {
        solve1();
        return 0;
    } else {
        solve2();
        return 0;
    }

    return 0;
}

/*

in:
1 5
B 0 A 4
B 1 B 3
A 5 B 7
B 2 A 6
B 1 A 7
ans: 24

in:
2 5
B 0 A 4
B 1 B 3
A 5 B 7
B 2 A 6
B 1 A 7
ans: 22


*/

#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...