1 solutions

  • 0
    @ 2025-7-6 22:33:46

    签到题,不用劳什子线段树,用 STL 就行了,但是常数会大一点,可能需要在 I/O 速度上找补一下。

    #include <stdio.h>
    #include <set>
    #include <algorithm>
    #include <chrono>
    #include <random>
    using namespace std;
    inline int rd()
    {
        int k = 0;
        char c = getchar();
        while (c < '0' || c > '9') c = getchar();
        while (c >= '0' && c <= '9') k = (k << 1) + (k << 3) + (c ^ '0'), c = getchar();
        return k;
    }
    const int N = 100010;
    int n, k;
    int a[N];
    
    struct info
    {
        pair<int, int> cal, ori;
        bool operator<(const info& o) const { return (cal == o.cal) ? (ori < o.ori) : (cal < o.cal); }
    };
    
    set<int> A;
    set<info> sum;
    inline void remove_A(int x)
    {
        if ((A.find(x) != A.begin()) && (A.upper_bound(x) != A.end()))
        {
            set<int>::iterator nxt = A.upper_bound(x), pre = --A.lower_bound(x);
            sum.erase({make_pair(*nxt - x, *nxt + x), make_pair(x, *nxt)});
            sum.erase({make_pair(x - *pre, x + *pre), make_pair(*pre, x)});
            sum.insert({make_pair(*nxt - *pre, *nxt + *pre), make_pair(*pre, *nxt)});
        } 
        else if (A.find(x) != A.begin())
        {
            set<int>::iterator pre = --A.lower_bound(x);
            sum.erase({make_pair(x - *pre, x + *pre), make_pair(*pre, x)});
        }
        else if (A.upper_bound(x) != A.end())
        {
            set<int>::iterator nxt = A.upper_bound(x);
            sum.erase({make_pair(*nxt - x, *nxt + x), make_pair(x, *nxt)});
        }
        A.erase(x);
    }
    inline void insert_A(int x)
    {
        if (A.count(x)) return;
        A.insert(x);
        if ((A.find(x) != A.begin()) && (A.upper_bound(x) != A.end()))
        {
            set<int>::iterator nxt = A.upper_bound(x), pre = --A.lower_bound(x);
            sum.insert({make_pair(*nxt - x, *nxt + x), make_pair(x, *nxt)});
            sum.insert({make_pair(x - *pre, x + *pre), make_pair(*pre, x)});
            sum.erase({make_pair(*nxt - *pre, *nxt + *pre), make_pair(*pre, *nxt)});
        } 
        else if (A.find(x) != A.begin())
        {
            set<int>::iterator pre = --A.lower_bound(x);
            sum.insert({make_pair(x - *pre, x + *pre), make_pair(*pre, x)});
        }
        else if (A.upper_bound(x) != A.end())
        {
            set<int>::iterator nxt = A.upper_bound(x);
            sum.insert({make_pair(*nxt - x, *nxt + x), make_pair(x, *nxt)});
        }
    }
    int main()
    {
        n = rd(), k = rd();
        for (int i = 1; i <= n; ++i) a[i] = rd();
        sort(a + 1, a + n + 1);
        for (int i = 1; i <= n; ++i) A.insert(a[i]);
        for (int i = 1; i < n; ++i) sum.insert({make_pair(a[i + 1] - a[i], a[i + 1] + a[i]), make_pair(a[i], a[i + 1])});
    
        int loop = 0;
        while (A.size() > 1)
        {
            info tmp = *sum.begin();
            sum.erase(sum.begin()), ++loop;
            remove_A(tmp.ori.first), remove_A(tmp.ori.second);
            int z = (tmp.ori.first + tmp.ori.second) % k;
            insert_A(z);
        }
        printf("%d\n%d", loop, *A.begin());
    }
    

    Information

    ID
    36
    Time
    1000ms
    Memory
    512MiB
    Difficulty
    2
    Tags
    # Submissions
    3
    Accepted
    1
    Uploaded By