Codeforces 908F New Year and Rainbow Roads

New Year and Rainbow Roads

思路:我们考虑两个绿点之间的红点和蓝点, 首先把这些红点和蓝点接到绿点上面绝对不会超过绿点距离的两倍。

然后我们先把两个绿点连上, 再把绿点经过蓝点到绿点的线连上, 绿点经过红点到绿点的线连上, 这时距离为3倍的绿点间距离,

然后我们可以在第二条路径和第三条路径上断开一段最长的, 和两个的绿点距离取个最小值,就是这段的贡献。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long
using namespace std;

const int N = 3e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;

int n, p, dis[N];
char s[3];
vector<int> G, R, B;

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d%s", &p, s);
        if(s[0] == 'G') G.push_back(p);
        else if(s[0] == 'R') R.push_back(p);
        else B.push_back(p);
    }
    LL ans = 0;
    if(SZ(G)) {
        int S = G[0], T = G[SZ(G)-1];
        if(SZ(R) && R[0] < S) ans += abs(R[0] - S);
        if(SZ(R) && R[SZ(R)-1] > T) ans += abs(R[SZ(R)-1] - T);
        if(SZ(B) && B[0] < S) ans += abs(B[0] - S);
        if(SZ(B) && B[SZ(B)-1] > T) ans += abs(B[SZ(B)-1] - T);
        for(int i = 0; i + 1 < SZ(G); i++) {
            LL l = G[i], r = G[i + 1];
            LL ret = 0, tmp1 = INF, tmp2 = INF;
            int x = lower_bound(R.begin(), R.end(), l) - R.begin();
            int y = lower_bound(R.begin(), R.end(), r) - R.begin() - 1;
            if(x <= y) {
                tmp1 = min(tmp1, r-l-(R[x]-l));
                tmp1 = min(tmp1, r-l-(r-R[y]));
                for(int j = x; j < y; j++) tmp1 = min(tmp1, r-l-(R[j+1]-R[j]));
            } else tmp1 = 0;
            x = lower_bound(B.begin(), B.end(), l) - B.begin();
            y = lower_bound(B.begin(), B.end(), r) - B.begin() - 1;
            if(x <= y) {
                tmp2 = min(tmp2, r-l-(B[x]-l));
                tmp2 = min(tmp2, r-l-(r-B[y]));
                for(int j = x; j < y; j++) tmp2 = min(tmp2, r-l-(B[j+1]-B[j]));
            } else tmp2 = 0;
            ans += min(2 * (r - l), tmp1 + tmp2 + r - l);
        }
    } else {
        if(SZ(R)) ans += R[SZ(R)-1] - R[0];
        if(SZ(B)) ans += B[SZ(B)-1] - B[0];
    }
    printf("%lld
", ans);
    return 0;
}

/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/10408048.html