Educational Codeforces Round 161 (Rated for Div. 2)

基本情况

A犯病卡半小时。

主要就是太着急,题目没有彻底分析清楚就开始想一些错误做法。

C最优想法出来的慢。

E比较好想。

C. Closest Cities

Problem - C - Codeforces

就,显然是能走最近城市就走,不行就不走。

一开始弄了一个自作聪明的预处理,但实际上每次查询还是 \(\operatorname O(n)\) 的复杂度,T 了第二个点。

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n + 1);
    vector<bool> tag(n + 1);
    vector<int> ind1, ind2;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= n; i++) {
        if (a[i + 1] - a[i] < a[i] - a[i - 1]) {
           tag[i] = true;
           ind1.emplace_back(i); 
        }
        else {
            tag[i] = false;
            ind2.emplace_back(i);
        }
    }
    int q;
    cin >> q;
    int x, y;
    while(q--) {
        cin >> x >> y;
        ll sum = 0;
        if (x <= y) {
            if (x == 1) {
                x++, sum++;
            }
            auto p = lower_bound(ind1.begin(), ind1.end(), x);
            for (int i = x; i < y; i++) {
                if (tag[i]) {
                    sum++;
                    p++;
                }
                else {
                    if (p == ind1.end()) {
                        sum += a[y] - a[i];
                        break;
                    }
                    int temp = *p;
                    if (temp > y) {
                        sum += a[y] - a[i];
                        break;
                    }
                    else {
                        sum += a[temp] - a[i];
                        i = temp;
                    }
                }
            }
        }
        else {
            if (x == n) {
                x--, sum++;
            }
            auto p = lower_bound(ind2.begin(), ind2.end(), x);
            if (p != ind2.begin() && *p != x) p--;
            for (int i = x; i > y; i--) {
                if (!tag[i]) {
                    sum++;
                    p--;
                }
                else {
                    if (p == ind2.begin()) {
                        sum += a[i] - a[y];
                        break;
                    }
                    if (*p < y) {
                        sum += a[i] - a[y];
                        break;
                    }
                    else {
                        sum += a[i] - a[*p];
                        i = *p;
                    }
                }
            }
        }
        cout << sum << endl;
    }
}

但这题显然可以把所有距离的答案都预处理掉,查询的时候直接类似前缀和 \(O(1)\)

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n + 1);
    vector<int> ind1(n + 1), ind2(n + 1);
    for (int i = 1; i <= n; i++) cin >> a[i];
    ind1[1] = 0;
    ind1[2] = ind1[1] + 1;
    for (int i = 3; i <= n; i++) {
        if (a[i - 1] - a[i - 2] > a[i] - a[i - 1]) {
            ind1[i] = ind1[i - 1] + 1;
        }
        else {
            ind1[i] = ind1[i - 1] + a[i] - a[i - 1];
        }
    }
    ind2[n] = 0;
    ind2[n - 1] = ind2[n] + 1; 
    for (int i = n - 2; i >= 1; i--) {
        if (a[i + 2] - a[i + 1] > a[i + 1] - a[i]) {
            ind2[i] = ind2[i + 1] + 1;
        }
        else {
            ind2[i] = ind2[i + 1] + a[i + 1] - a[i];
        }
    }
    int q;
    cin >> q;
    int x, y;
    while(q--) {
        cin >> x >> y;
        if (x <= y) {
            cout << ind1[y] - ind1[x] << endl;
        }
        else {
            cout << ind2[y] - ind2[x] << endl;
        }
    }
}

这题 \(+3\),应该在第一次 T 了之后就重写做法了,但是还想着在原来那个方法上面优化,导致疯狂罚时。

posted @ 2024-01-20 10:58  加固文明幻景  阅读(39)  评论(0编辑  收藏  举报