QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#878017#8591. ShopsNauclhltCompile Error//C++1724.2kb2025-02-01 13:05:572025-02-01 13:05:57

Judging History

你现在查看的是最新测评结果

  • [2025-02-01 13:05:57]
  • 评测
  • [2025-02-01 13:05:57]
  • 提交

answer

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <random>

using namespace std;

using ll = long long;

template <typename T>
struct Edge
{
    int From;
    int To;
    T Weight;

public:
    Edge(int from, int to, T weight)
    {
        From = from;
        To = to;
        Weight = weight;
    }
};

struct Point 
{
public:
    int X;
    int Y;

    Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    friend bool operator==(Point left, Point right)
    {
        return left.X == right.X && left.Y == right.Y;
    }

    friend bool operator<(Point left, Point right)
    {
        return tie(left.X, left.Y) < tie(right.X, right.Y);
    }
};

struct PointHash
{
    size_t operator()(Point point)
    {
        return hash<int>()(point.X) ^ hash<int>()(point.Y);
    }
};


class UnionFind
{
private:
    vector<int> _parents;
    vector<int> _size;
    int _vertexCount;

public:
    UnionFind(int n)
    {
        _vertexCount = n;
        _parents.resize(n);
        _size.resize(n);
        for (int i = 0; i < n; i++)
        {
            _size[i] = 1;
            _parents[i] = i;
        }
    }

    int Root(int x)
    {
        if (_parents[x] == x) return x;
        
        return _parents[x] = Root(_parents[x]);
    }

    int Size(int x)
    {
        return _size[Root(x)];
    }

    void Unite(int x, int y)
    {
        int rootX = Root(x);
        int rootY = Root(y);

        if (rootX == rootY) return;

        int from = rootX;
        int to = rootY;

        if (_size[from] > _size[to])
        {
            swap(from, to);
        }

        _size[to] += _size[from];
        _parents[from] = to;
    }

    vector<int> Find(int x)
    {
        int root = Root(x);
        vector<int> set;
        for (int i = 0; i < _vertexCount; i++)
        {
            if (Root(i) == root)
            {
                set.push_back(i);
            }
        }

        return set;
    }

    unordered_map<int, vector<int>> FindAll()
    {
        unordered_map<int, vector<int>> sets;
        for (int i = 0; i < _vertexCount; i++)
        {
            int root = Root(i);
            if (sets.find(root) != sets.end())
            {
                sets[root].push_back(i);
            }
            else
            {
                sets.emplace(root, vector<int>());
                sets[root].push_back(i);
            }
        }

        return sets;
    }

    bool Same(int x, int y)
    {
        int rootX = Root(x);
        int rootY = Root(y);
        return rootX == rootY;
    }

    void Clear()
    {
        for (int i = 0; i < _vertexCount; i++)
        {
            _parents[i] = i;
            _size[i] = 1;
        }
    }

    int VertexCount()
    {
        return _vertexCount;
    }
};

template <typename T>
class Imos
{
private:
    vector<T> _data;

public:
    Imos(int length)
    {
        _data.resize(length, 0);
    }

    Imos(vector<T>& array)
    {
        _data = array;
    }

    void AddQueryLen(int start, int length, T value)
    {
        AddQuery(start, start + length, value);
    }

    void AddQuery(int start, int end, T value)
    {
        _data[start] += value;
        if (end < (int)_data.size())
        {
            _data[end] -= value;
        }
    }

    void Accumulate()
    {
        for (int i = 1; i < (int)_data.size(); i++)
        {
            _data[i] += _data[i - 1];
        }
    }

    vector<T> GetData()
    {
        return _data;
    }
};

template <typename T>
class Imos2D
{
private:
    vector<vector<T>> _data;
    int _width;
    int _height;

public:
    Imos2D(vector<vector<T>> data)
    {
        _data = data;
        _height = data.size();
        _width = data[0].size();
    }

    Imos2D(int h, int w)
    {
        _data.resize(h, vector<T>(w, 0));
        _width = w;
        _height = h;
    }

    void AddQuery(int startX, int startY, int endX, int endY, T value)
    {
        _data[startY][startX] += value;
        if (endX < _width)
        {
            _data[startY][endX] -= value;
        }
        if (endY < _height)
        {
            _data[endY][startX] -= value;
        }
        if (endX < _width && endY < _height)
        {
            _data[endY][endX] += value;
        }
    }

    void AddQueryLen(int x, int y, int w, int h, T value)
    {
        AddQuery(x, y, x + w, y + h, value);
    }

    void Accumulate()
    {
        for (int x = 1; x < _width; x++)
        {
            for (int y = 0; y < _height; y++)
            {
                _data[y][x] += _data[y][x - 1];
            }
        }

        for (int y = 1; y < _height; y++)
        {
            for (int x = 0; x < _width; x++)
            {
                _data[y][x] += _data[y - 1][x];
            }
        }
    }

    vector<vector<T>> GetData()
    {
        return _data;
    }
};

template<typename T, T OP(T, T), T APPLY(T, T)>
class SegmentTree
{
private:
    int _treeSize;
    int _dataSize;
    int _originalDataSize;
    vector<T> _data;
    T _identity;

public:
    SegmentTree(int n, T identity)
    {
        _originalDataSize = n;
        _identity = identity;

        int size = 1;
        while (n > size)
        {
            size <<= 1;
        }

        _dataSize = size;
        _treeSize = 2 * size - 1;

        _data.resize(_treeSize, _identity);
    }

    int OriginalDataSize()
    {
        return _originalDataSize;
    }

    int TreeSize()
    {
        return _treeSize;
    }

    T Identity()
    {
        return _identity;
    }

    void Build(vector<T>& array)
    {
        if (_originalDataSize != (int)array.size())
        {
            throw exception();
        }

        for (int i = 0; i < (int)array.size(); i++)
        {
            _data[i + _dataSize - 1] = array[i];
        }

        for (int i = _dataSize - 2; i >= 0; i--)
        {
            _data[i] = OP(_data[(i << 1) + 1], _data[(i << 1) + 2]);
        }
    }

    void Apply(int index, T value)
    {
        index += _dataSize - 1;
        _data[index] = APPLY(_data[index], value);

        while (index > 0)
        {
            index = (index - 1) >> 1;
            _data[index] = OP(_data[(index << 1) + 1], _data[(index << 1) + 2]);
        }
    }

    T Query(int left, int right)
    {
        return QueryRec(left, right, 0, 0, _dataSize);
    }

    const T& operator[](size_t index) const
    {
        return _data[_dataSize - 1 + index];
    }

    T& operator[](size_t index)
    {
        return _data[_dataSize - 1 + index];
    }

private:
    T QueryRec(int left, int right, int index, int l, int r)
    {
        if (left >= r || right <= l)
        {
            return _identity;
        }

        if (left <= l && r <= right)
        {
            return _data[index];
        }

        return OP(QueryRec(left, right, (index << 1) + 1, l, (l + r) / 2), QueryRec(left, right, (index << 1) + 2, (l + r) / 2, r));
    }
};

template <typename T, typename M, T OP(T, T), T MAPPING(T, M, int), T COMPOSITION(T, T)>
class LazySegmentTree
{
private:
    int _treeSize;
    int _dataSize;
    int _originalDataSize;
    vector<T> _data;
    vector<optional<T>> _lazy;
    T _identity;

public:
    LazySegmentTree(int n, T identity)
    {
        _originalDataSize = n;
        _identity = identity;

        int size = 1;
        while (n > size)
        {
            size <<= 1;
        }

        _dataSize = size;
        _treeSize = 2 * size - 1;

        _data.resize(_treeSize, _identity);
        _lazy.resize(_treeSize, nullopt);
    }

    void Build(vector<T>& array)
    {
        if (_originalDataSize != (int)array.size())
        {
            throw exception();
        }

        for (int i = 0; i < (int)array.size(); i++)
        {
            _data[i + _dataSize - 1] = array[i];
        }

        for (int i = _dataSize - 2; i >= 0; i--)
        {
            _data[i] = OP(_data[(i << 1) + 1], _data[(i << 1) + 2]);
        }
    }

    int TreeSize()
    {
        return _treeSize;
    }

    int OriginalDataSize()
    {
        return _originalDataSize;
    }

    void Apply(int left, int right, M m)
    {
        ApplyRec(left, right, m, 0, 0, _dataSize);
    }

    T Query(int left, int right)
    {
        return QueryRec(left, right, 0, 0, _dataSize);
    }

    T GetByIndex(int index)
    {
        if (index < 0 || index >= _originalDataSize)
        {
            throw exception();
        }

        return AccessRec(index, 0, 0, _dataSize);
    }

private:
    void Evaluate(int index, int l, int r)
    {
        if (!_lazy[index].has_value())
        {
            return;
        }

        if (index < _dataSize - 1)
        {
            _lazy[(index << 1) + 1] = GuardComposition(_lazy[(index << 1) + 1], _lazy[index]);
            _lazy[(index << 1) + 2] = GuardComposition(_lazy[(index << 1) + 2], _lazy[index]);
        }

        _data[index] = MAPPING(_data[index], _lazy[index].value(), r - l);
        _lazy[index] = nullopt;
    }

    optional<M> GuardComposition(optional<M> a, optional<M> b)
    {
        if (!a.has_value())
        {
            return b;
        }
        else
        {
            return COMPOSITION(a.value(), b.value());
        }
    }

    void ApplyRec(int left, int right, M m, int index, int l, int r)
    {
        Evaluate(index, l, r);

        if (left <= l && r <= right)
        {
            _lazy[index] = GuardComposition(_lazy[index], m);
            Evaluate(index, l, r);
        }
        else if (left < r && l < right)
        {
            ApplyRec(left, right, m, (index << 1) + 1, l, (l + r) / 2);
            ApplyRec(left, right, m, (index << 1) + 2, (l + r) / 2, r);
            _data[index] = OP(_data[(index << 1) + 1], _data[(index << 1) + 2]);
        }
    }

    T QueryRec(int left, int right, int index, int l, int r)
    {
        Evaluate(index, l, r);

        if (left >= r || right <= l)
        {
            return _identity;
        }

        if (left <= l && r <= right)
        {
            return _data[index];
        }

        return OP(QueryRec(left, right, (index << 1) + 1, l, (l + r) / 2), QueryRec(left, right, (index << 1) + 2, (l + r) / 2, r));
    }

    T AccessRec(int target, int index, int l, int r)
    {
        Evaluate(index, l, r);

        if (index >= _dataSize - 1)
        {
            return _data[index];
        }

        int mid = (l + r) / 2;
        
        if (target < mid)
        {
            return AccessRec(target, (index << 1) + 1, l, mid);
        }
        else
        {
            return AccessRec(target, (index << 1) + 2, mid, r);
        }
    }
};

#define CONST_MOD 998244353LL
//#define CONST_MOD 1000000007LL
struct ModInt
{
    long long Value;

public:
    ModInt()
    {
        Value = 0L;
    }

    ModInt(long long value)
    {
        Value = value;
    }

    ModInt Power(long long exp) const
    {
        if (exp <= -1L)
        {
            return ModInt(1L) / Power(-exp);
        }
        if (exp == 0L)
            return 1L;
        if (exp == 1L)
            return *this;

        ModInt m = Power(exp / 2L);
        m = m * m;
        if (exp % 2L == 1L)
        {
            m = m * (*this);
        }

        return m;
    }

    ModInt Inv() const
    {
        return this->Power(CONST_MOD - 2L);
    }

    ModInt operator+() const
    {
        return *this;
    }

    ModInt operator-() const
    {
        return ModInt(-Value);
    }

    friend ModInt operator+(const ModInt& left, const ModInt& right)
    {
        return ModInt(SafeMod(left.Value + right.Value));
    }

    friend ModInt operator+(const ModInt& left, const long long& right)
    {
        return ModInt(SafeMod(left.Value + right));
    }

    friend ModInt operator+(const long long& left, const ModInt& right)
    {
        return ModInt(SafeMod(left + right.Value));
    }

    ModInt& operator+=(const ModInt& x)
    {
        Value += x.Value;
        Value = SafeMod(Value);

        return *this;
    }

    ModInt& operator+=(const long long& x)
    {
        Value += x;
        Value = SafeMod(Value);

        return *this;
    }

    friend ModInt operator-(const ModInt& left, const ModInt& right)
    {
        return ModInt(SafeMod(left.Value - right.Value));
    }

    friend ModInt operator-(const ModInt& left, const long long& right)
    {
        return ModInt(SafeMod(left.Value - right));
    }

    friend ModInt operator-(const long long& left, const ModInt& right)
    {
        return ModInt(SafeMod(left - right.Value));
    }

    ModInt& operator-=(const ModInt& x)
    {
        Value -= x.Value;
        Value = SafeMod(Value);

        return *this;
    }

    ModInt& operator-=(const long long& x)
    {
        Value -= x;
        Value = SafeMod(Value);

        return *this;
    }

    friend ModInt operator*(const ModInt& left, const ModInt& right)
    {
        return ModInt(SafeMod(left.Value * right.Value));
    }

    friend ModInt operator*(const ModInt& left, const long long& right)
    {
        return ModInt(SafeMod(left.Value * right));
    }

    friend ModInt operator*(const long long& left, const ModInt& right)
    {
        return ModInt(SafeMod(left * right.Value));
    }

    ModInt& operator*=(const ModInt& x)
    {
        Value *= x.Value;
        Value = SafeMod(Value);

        return *this;
    }

    ModInt& operator*=(const long long& x)
    {
        Value *= x;
        Value = SafeMod(Value);

        return *this;
    }

    friend ModInt operator /(const ModInt& left, const ModInt& right)
    {
        ModInt inv = right.Inv();
        return ModInt(SafeMod(left.Value * inv.Value));
    }

    friend ModInt operator/(const ModInt& left, const long long& right)
    {
        return ModInt(SafeMod(left.Value * ModInt(right).Inv().Value));
    }

    friend ModInt operator/(const long long& left, const ModInt& right)
    {
        return ModInt(SafeMod(left * right.Inv().Value));
    }

    ModInt& operator/=(const ModInt& x)
    {
        Value *= x.Inv().Value;
        Value = SafeMod(Value);

        return *this;
    }

    ModInt& operator/=(const long long& x)
    {
        Value *= ModInt(x).Inv().Value;
        Value = SafeMod(Value);

        return *this;
    }

    ModInt& operator++()
    {
        ++Value;
        Value = SafeMod(Value);
        return *this;
    }

    ModInt operator++(int)
    {
        ModInt temp = *this;
        Value++;
        Value = SafeMod(Value);
        return temp;
    }

    ModInt& operator--()
    {
        --Value;
        Value = SafeMod(Value);
        return *this;
    }

    ModInt operator--(int)
    {
        ModInt temp = *this;
        Value--;
        Value = SafeMod(Value);
        return temp;
    }

    inline static ModInt One()
    {
        return ModInt(1L);
    }

    static ModInt Combination(long long n, long long r)
    {
        ModInt c = 1L;
        for (ModInt i = 1; i.Value <= r; i++)
        {
            c = c * (ModInt(n) - i + ModInt::One()) / i;
        }
        return c;
    }

private:
    inline static long long SafeMod(long long a)
    {
        a %= CONST_MOD;
        if (a < 0)
        {
            a += CONST_MOD;
        }
        return a;
    }
};

//

template <typename T>
class Graph
{
private:
    vector<vector<Edge<T>>> _graph;
    vector<Edge<T>> _edges;
    vector<bool> _seen;
    unique_ptr<UnionFind> _uf;
    int _vertexCount;

public:
    Graph(int vertexCount)
    {
        _vertexCount = vertexCount;
        _graph.resize(_vertexCount);
        _edges.reserve(_vertexCount);
        _seen.resize(_vertexCount);
        _uf = NULL;
    }

    int VertexCount()
    {
        return _vertexCount;
    }

    vector<vector<Edge<T>>>& RawGraph()
    {
        return _graph;
    }

    vector<Edge<T>>& Edges()
    {
        return _edges;
    }

    UnionFind DSU()
    {
        return *_uf;
    }

    void AddEdge(int a, int b, T weight)
    {
        if (!Validate(a) || !Validate(b))
        {
            return;
        }

        if (a > b)
        {
            swap(a, b);
        }

        _graph[a].push_back(Edge<T>(a, b, weight));
        _graph[b].push_back(Edge<T>(b, a, weight));
        _edges.push_back(Edge<T>(a, b, weight));
    }

    void SetupDSU()
    {
        _uf.reset(new UnionFind(_vertexCount));
        for (int i = 0; i < (int)_edges.size(); i++)
        {
            _uf->Unite(_edges[i].From, _edges[i].To);
        }
    }

    bool Same(int a, int b)
    {
        if (_uf == nullptr)
        {
            throw exception();
        }
        return _uf->Same(a, b);
    }

    unordered_map<int, vector<int>> GetConnectedComponents()
    {
        if (_uf == nullptr)
        {
            throw exception();
        }
        return _uf->FindAll();
    }

    void DijkstraFrom(int n, vector<T>& map)
    {
        if (!Validate(n))
        {
            return;
        }

        fill(_seen.begin(), _seen.end(), false);

        fill(map.begin(), map.end(), numeric_limits<T>::max());
        map[n] = 0;

        priority_queue<pair<T, int>, vector<pair<T, int>>, greater<pair<T, int>>> pq;
        pq.emplace(0, n);

        while (!pq.empty())
        {
            T c = pq.top().first;
            int p = pq.top().second;
            pq.pop();

            if (_seen[p])
            {
                continue;
            }

            _seen[p] = true;

            vector<Edge<T>>& ch = _graph[p];
            for (int i = 0; i < (int)ch.size(); i++)
            {
                T w = map[p] + ch[i].Weight;
                if (w < map[ch[i].To])
                {
                    map[ch[i].To] = w;
                    pq.emplace(w, ch[i].To);
                }
            }
        }
    }

    vector<vector<T>> WarshallFloyd()
    {
        if (_vertexCount > 800)
        {
            throw exception();
        }

        T inf = numeric_limits<T>::max();

        vector<vector<T>> map(_vertexCount, vector<T>(_vertexCount, inf));

        for (int i = 0; i < _vertexCount; i++)
        {
            map[i][i] = 0;
        }

        for (int i = 0; i < (int)_edges.size(); i++)
        {
            map[_edges[i].From][_edges[i].To] = min(_edges[i].Weight, map[_edges[i].From][_edges[i].To]);
            map[_edges[i].To][_edges[i].From] = min(_edges[i].Weight, map[_edges[i].To][_edges[i].From]);
        }

        for (int k = 0; k < _vertexCount; k++)
        {
            for (int j = 0; j < _vertexCount; j++)
            {
                for (int i = 0; i < _vertexCount; i++)
                {
                    if (map[i][k] != inf && map[k][j] != inf)
                    {
                        if (map[i][k] + map[k][j] < map[i][j])
                        {
                            map[i][j] = map[i][k] + map[k][j];
                        }
                    }
                }
            }
        }

        return map;
    }

    void BfsFrom(int n, vector<T>& map)
    {
        if (!Validate(n))
        {
            return;
        }

        fill(_seen.begin(), _seen.end(), false);

        map[n] = 0;

        queue<pair<int, T>> queue;

        queue.emplace(n, 0);

        while (!queue.empty())
        {
            int p = queue.front().first;
            T w = queue.front().second;
            queue.pop();

            if (_seen[p])
                continue;

            _seen[p] = true;
            map[p] = w;

            vector<Edge<T>>& ch = _graph[p];
            for (int i = 0; i < (int)ch.size(); i++)
            {
                queue.emplace(ch[i].To, w + ch[i].Weight);
            }
        }
    }

    Graph<T> CreateComplement() 
    {
        struct pair_hash {
            inline std::size_t operator()(const std::pair<int,int> & v) const {
                return v.first ^ v.second;
            }
        };

        unordered_set<pair<int, int>, pair_hash> edgeSet;
        for (int i = 0; i < (int)_edges.size(); i++)
        {
            edgeSet.emplace(_edges[i].From, _edges[i].To);
        }

        Graph<T> g(_vertexCount);

        for (int i = 0; i < _vertexCount - 1; i++)
        {
            for (int j = i + 1; j < _vertexCount; j++)
            {
                if (edgeSet.find(make_pair(i, j)) == edgeSet.end())
                {
                    cout << i << ", " << j << endl;
                    g.AddEdge(i, j, 0);
                }
            }
        }

        return g;
    }
    
    bool IsBipartite()
    {
        fill(_seen.begin(), _seen.end(), false);

        stack<pair<int, bool>> stack;

        vector<bool> memo(_vertexCount);

        for (int i = 0; i < _vertexCount; i++)
        {
            if (_seen[i]) continue;

            stack.emplace(i, false);

            while (!stack.empty())
            {
                int n = stack.top().first;
                bool c = stack.top().second;
                stack.pop();

                if (_seen[n])
                {
                    if (memo[n] != c)
                    {
                        return false;
                    }

                    continue;
                }

                _seen[n] = true;
                memo[n] = c;

                vector<Edge<T>>& ch = _graph[n];
                for (int j = 0; j < (int)ch.size(); j++)
                {
                    stack.emplace(ch[j].To, !c);
                }
            }
        }

        return true;
    }

    T TreeDiameter()
    {
        if ((int)_edges.size() != _vertexCount - 1)
        {
            throw exception();
        }

        vector<T> dist(_vertexCount);

        BfsFrom(0, dist);

        T max = 0;
        int v = 0;
        for (int i = 0; i < _vertexCount; i++)
        {
            if (dist[i] > max)
            {
                max = dist[i];
                v = i;
            }
        }

        fill(dist.begin(), dist.end(), 0);

        BfsFrom(v, dist);

        max = 0;
        for (int i = 0; i < _vertexCount; i++)
        {
            if (dist[i] > max)
            {
                max = dist[i];
            }
        }

        return max;
    }

    T MaxSpanningTreeWeight()
    {
        UnionFind unionFind(_vertexCount);

        T ans = 0;

        auto cmp = [](const Edge<T> &a, const Edge<T> &b)
        {
            return a.Weight > b.Weight;
        };

        vector<Edge<T>>& edges = _edges;

        sort(edges.begin(), edges.end(), cmp);

        for (int i = 0; i < (int)edges.size(); i++)
        {
            if (!unionFind.Same(edges[i].From, edges[i].To))
            {
                unionFind.Unite(edges[i].From, edges[i].To);
                ans += edges[i].Weight;
            }
        }

        return ans;
    }

    T MinSpanningTreeWeight()
    {
        UnionFind unionFind(_vertexCount);

        T ans = 0;

        auto cmp = [](const Edge<T> &a, const Edge<T> &b)
        {
            return a.Weight < b.Weight;
        };

        vector<Edge<T>>& edges = _edges;

        sort(edges.begin(), edges.end(), cmp);

        for (int i = 0; i < (int)edges.size(); i++)
        {
            if (!unionFind.Same(edges[i].From, edges[i].To))
            {
                unionFind.Unite(edges[i].From, edges[i].To);
                ans += edges[i].Weight;
            }
        }

        return ans;
    }

private:
    inline bool Validate(int n)
    {
        return 0 <= n && n < _vertexCount;
    }
};

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    
    vector<vector<int>> mst(n, vector<int>());
    UnionFind uf(n);

    vector<pair<ll, pair<int, int>>> edges;
    for (int i = 0; i < m; i++)
    {
        int u, v;
        cin >> u >> v;
        u--;v--;
        ll w;
        cin >> w;

        edges.emplace_back(w, make_pair(u, v));
    }

    sort(edges.begin(), edges.end());

    ll ans = 0;
    for (int i = 0; i < edges.size(); i++)
    {
        int a = edges[i].second.first;
        int b = edges[i].second.second;
        if (!uf.Same(a, b))
        {
            uf.Unite(a, b);
            mst[a].push_back(b);
            mst[b].push_back(a);
            chmax(ans, edges[i].first);
        }
    }

    queue<pair<int, bool>> q;
    q.emplace(0, false);

    vector<bool> built(n);
    vector<bool> seen(n);

    while (!q.empty())
    {
        int p = q.front().first;
        bool b = q.front().second;
        q.pop();

        if (seen[p]) continue;

        seen[p] = true;
        built[p] = b;

        for (int j = 0; j < mst[p].size(); j++)
        {
            q.emplace(mst[p][j], !b);
        }
    }

    cout << ans << endl;
    for (int i = 0; i < n; i++)
    {
        if (built[i]) cout << "B";
        else cout << "D";
    }
    cout << endl;
}

详细

answer.code: In function ‘int main()’:
answer.code:1197:13: error: ‘chmax’ was not declared in this scope
 1197 |             chmax(ans, edges[i].first);
      |             ^~~~~