首页 > 其他分享 >Solution Set【2024.2.15】

Solution Set【2024.2.15】

时间:2024-02-15 20:34:09浏览次数:34  
标签:std 2024.2 Set 15 auto valueType typedef const id

A. 枇杷树

考虑从增量的角度计算答案,若我们在构造树 \(T_n\) 时已经得到了树 \(T_x\) 和 树 \(T_y\) 的答案 \(Ans_x\) 和 \(Ans_y\),我们考虑如何得出 \(Ans_n\)。

考虑 \(Ans_n\) 与 \(Ans_x + Ans_y\),发现即为跨越新增的边的所有路径权值之和。其可以表达为:

\[f(x, u) \times size_y + f(y, v) \times size_x + w \times size_x \times size_y \]

其中 \(f(n, p) = \sum\limits_{0 \le i < size_n} \operatorname{dist}(p, i)\) 即在 \(T_n\) 中 \(p\) 与所有节点的距离之和。考虑如何求出 \(f(n, p)\),不妨通过递归求出,考虑 \(p\) 在哪棵树中,那么另一棵子树的贡献可以拆分为连接点到其所有节点的距离之和再加上连接点到 \(p\) 的距离即可,不妨设 \(p\) 在 \(T_x\) 中,那么我们有:

\[f(n, p) = f(x, p) + f(y, v) + g(n, x, v) \times size_y \]

其中 \(g(n, p, q)\) 表示在 \(T_n\) 中 \(p, q\) 两点间的距离。求解其也可以通过讨论其在构造树 \(T_n\) 前属于的两棵子树进行递归求解。

我们下面尝试论证其复杂度,我们设在构造树的过程中连接其他树的节点为关键点,不难发现除去所有关键点之间的状态外,每次求解 \(f, g\) 使用到的状态数均为 \(\mathcal{O}(m)\),而所有关键点之间的状态数为 \(\mathcal{O}(m^2)\)。而我们需要求解 \(f, g\) 共 \(\mathcal{O}(m)\) 次。因此复杂度为 \(\mathcal{O}(m^3)\)。

Code
#include <bits/stdc++.h>

typedef long long valueType;
typedef std::vector<valueType> ValueVector;
typedef std::pair<valueType, valueType> ValuePair;
typedef std::map<ValuePair, valueType> ValueMap;
typedef std::vector<ValueMap> MapMatrix;
typedef std::tuple<valueType, valueType, valueType, valueType, valueType> ValueTuple;
typedef std::vector<ValueTuple> TupleVector;

namespace MODINT {
    constexpr valueType MOD = 1e9 + 7;

    template<typename T1, typename T2>
    T1 sum(T1 a, T2 b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }

    template<typename T1, typename T2>
    T1 sub(T1 a, T2 b) {
        return a - b < 0 ? a - b + MOD : a - b;
    }

    template<typename T1, typename T2>
    void Inc(T1 &a, T2 b) {
        a += b;

        if (a >= MOD)
            a -= MOD;
    }

    template<typename T1, typename T2>
    void Dec(T1 &a, T2 b) {
        a -= b;

        if (a < 0)
            a += MOD;
    }

    template<typename T1, typename T2>
    T1 mul(T1 a, T2 b) {
        return (long long) a * b % MOD;
    }

    template<typename T1, typename T2>
    void Mul(T1 &a, T2 b) {
        a = (long long) a * b % MOD;
    }
} // namespace MODINT

using namespace MODINT;

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

#ifndef LOCAL_STDIO
    freopen("loquat.in", "r", stdin);
    freopen("loquat.out", "w", stdout);
#endif

    valueType M;

    std::cin >> M;

    ValueVector Size(M + 1, 0);
    TupleVector Tree(M + 1);
    ValueVector Ans(M + 1, 0);

    Size[0] = 1;

    for (valueType i = 1; i <= M; ++i) {
        auto &[x, y, u, v, w] = Tree[i];

        std::cin >> x >> y >> u >> v >> w;

        Size[i] = Size[x] + Size[y];
    }

    ValueMap MemoryF;
    MapMatrix MemoryG(M + 1);

    MemoryF[std::make_pair(0, 0)] = 0;
    MemoryG[0][std::make_pair(0, 0)] = 0;

    auto G = [&](auto self, valueType n, valueType x, valueType y) -> valueType {
        if (x > y)
            std::swap(x, y);

        if (MemoryG[n].count(std::make_pair(x, y)))
            return MemoryG[n][std::make_pair(x, y)];

        valueType &result = MemoryG[n][std::make_pair(x, y)];

        auto const [l, r, u, v, w] = Tree[n];

        if (y < Size[l]) { // both in tree l
            Inc(result, self(self, l, x, y));
        } else if (x >= Size[l]) { // both in tree r
            Inc(result, self(self, r, x - Size[l], y - Size[l]));
        } else {
            Inc(result, self(self, l, x, u));

            Inc(result, w);

            Inc(result, self(self, r, y - Size[l], v));
        }

        return result;
    };

    auto F = [&](auto self, valueType n, valueType x) -> valueType {
        if (MemoryF.count(std::make_pair(n, x)))
            return MemoryF[std::make_pair(n, x)];

        valueType &result = MemoryF[std::make_pair(n, x)];

        auto const [l, r, u, v, w] = Tree[n];

        if (x >= Size[l]) { // in tree r
            Inc(result, self(self, l, u));

            Inc(result, mul(G(G, n, u, x), Size[l] % MOD));

            Inc(result, self(self, r, x - Size[l]));
        } else { // in tree l
            Inc(result, self(self, r, v));

            Inc(result, mul(G(G, n, v + Size[l], x), Size[r] % MOD));

            Inc(result, self(self, l, x));
        }

        return result;
    };

    for (valueType i = 1; i <= M; ++i) {
        auto const &[x, y, u, v, w] = Tree[i];

        Ans[i] = sum(Ans[x], Ans[y]);

        Inc(Ans[i], mul(F(F, x, u), Size[y] % MOD));
        Inc(Ans[i], mul(F(F, y, v), Size[x] % MOD));
        Inc(Ans[i], mul(w, mul(Size[x] % MOD, Size[y] % MOD)));
    }

    for (valueType i = 1; i <= M; ++i)
        std::cout << Ans[i] << std::endl;

    return 0;
}

B. 上古遗迹

对于 \(i\),设 \(\left[a_i, b_i\right]\) 为极长的区间满足其最小值为 \(h_i\)。

那么我们要求解的为:

\[\max\limits_{i = 1}^{n} \left(\min\left\{r, b_i\right\} - \max\left\{l, a_i\right\} + 1\right) \times h_i \]

我们考虑通过讨论 \(l, r\) 与 \(a, b\) 的关系求解。发现其实际上只有如下四种关系:

  • \(l \le a \le b \le r\)。
  • \(a \le l \le r \le b\)。
  • \(a \le l \le b \le r\)。
  • \(l \le a \le r \le b\)。

前两种可以通过对右端点进行扫描线,然后使用线段树维护左端点答案即可求解,不多赘述。而第四种可以通过将序列和询问均翻转进而得到第三种情况,因此下文主要讨论如何求解第三种情况。

发现此时答案为:

\[\begin{aligned} &\left(b_i - l + 1\right) \times h_i \\ =&-l \times h_i + \left(b_i + 1\right) \times h_i \end{aligned}\]

发现其可以表达为关于 \(l\) 一次函数的形式,进而我们的问题转化为了,对于每个询问在所有满足 \(a_i \le l \le b_i\) 且 \(b_i \le r\) 的一次函数中寻找在位置 \(l\) 的最小值即可。

我们考虑通过扫描线来处理第二个限制,而第一个限制实际上为一次函数的定义域限制,通过李超线段树即可解决。

复杂度为 \(\mathcal{O}(n\log n^2)\)。

Code
#include <bits/stdc++.h>

typedef long long valueType;
typedef std::vector<valueType> ValueVector;
typedef std::vector<ValueVector> ValueMatrix;
typedef std::pair<valueType, valueType> ValuePair;
typedef std::vector<ValuePair> PairVector;
typedef std::vector<PairVector> PairMatrix;
typedef std::stack<valueType> ValueStack;
typedef std::tuple<valueType, valueType, valueType, valueType> ValueTuple;
typedef std::vector<ValueTuple> TupleVector;

constexpr valueType MIN = std::numeric_limits<valueType>::min() >> 1;

class Tree {
private:
    valueType N;
    ValueVector data;

    void Merge(valueType id) {
        data[id] = std::max(data[id << 1], data[id << 1 | 1]);
    }

public:
    Tree() = default;

    Tree(valueType n) : N(n), data(4 * N + 10, -1) {}

public:
    void Modify(valueType x, valueType v) {
        Modify(1, 1, N, x, v);
    }

    valueType Query(valueType l, valueType r) {
        return Query(1, 1, N, l, r);
    }

private:
    void Modify(valueType id, valueType nodeL, valueType nodeR, valueType x, valueType v) {
        if (nodeL == nodeR) {
            data[id] = std::max(data[id], v);

            return;
        }

        valueType const mid = (nodeL + nodeR) >> 1;

        if (x <= mid)
            Modify(id << 1, nodeL, mid, x, v);
        else
            Modify(id << 1 | 1, mid + 1, nodeR, x, v);

        Merge(id);
    }

    valueType Query(valueType id, valueType nodeL, valueType nodeR, valueType queryL, valueType queryR) const {
        if (queryL <= nodeL && nodeR <= queryR)
            return data[id];

        valueType const mid = (nodeL + nodeR) >> 1;

        if (queryR <= mid)
            return Query(id << 1, nodeL, mid, queryL, queryR);
        else if (queryL > mid)
            return Query(id << 1 | 1, mid + 1, nodeR, queryL, queryR);
        else
            return std::max(Query(id << 1, nodeL, mid, queryL, queryR), Query(id << 1 | 1, mid + 1, nodeR, queryL, queryR));
    }
};

class LiChaoTree {
private:
    struct Line {
        valueType K, B;

        Line() : K(0), B(MIN){};

        Line(valueType k, valueType b) : K(k), B(b) {}

        valueType operator()(valueType x) const {
            return K * x + B;
        }
    };

private:
    struct Node {
        valueType leftBound, rightBound, mid;

        valueType leftSon, rightSon;

        Line data;

        Node() : leftBound(0), rightBound(-1), mid(-1), leftSon(-1), rightSon(-1), data() {}

        Node(valueType l, valueType r) : leftBound(l), rightBound(r), mid((l + r) >> 1), leftSon(-1), rightSon(-1), data() {}

        Node(valueType l, valueType r, Line line) : leftBound(l), rightBound(r), mid((l + r) >> 1), leftSon(-1), rightSon(-1), data(line) {}
    };

private:
    valueType N, PoolSize;
    valueType root;
    std::vector<Node> Tree;

    valueType Allocate() {
        if (PoolSize + 1 >= Tree.size())
            Tree.resize(Tree.size() << 1);

        return ++PoolSize;
    }

public:
    LiChaoTree() : N(0), PoolSize(0), root(-1), Tree() {}

    LiChaoTree(valueType n) : N(n), PoolSize(0), root(-1), Tree(4 * N + 10) {}

public:
    void Push(valueType l, valueType r, valueType k, valueType b) {
        Push(root, 1, N, l, r, Line(k, b));
    }

    valueType Query(valueType x) {
        return Query(root, 1, N, x);
    }

private:
    void Push(valueType &id, valueType l, valueType r, Line Next) {
        if (id == -1) {
            id = Allocate();

            Tree[id] = Node(l, r, Next);
        }

        auto &Prev = Tree[id].data;

        valueType const mid = Tree[id].mid;

        if (Next(mid) > Prev(mid))
            std::swap(Next, Prev);

        if (Next(l) > Prev(l))
            Push(Tree[id].leftSon, l, mid, Next);
        else if (Next(r) > Prev(r))
            Push(Tree[id].rightSon, mid + 1, r, Next);
    }

    void Push(valueType &id, valueType nodeL, valueType nodeR, valueType queryL, valueType queryR, Line const &line) {
        if (id == -1) {
            id = Allocate();

            Tree[id] = Node(nodeL, nodeR);
        }

        if (queryL <= nodeL && nodeR <= queryR) {
            Push(id, nodeL, nodeR, line);

            return;
        }

        valueType const mid = (nodeL + nodeR) >> 1;

        if (queryL <= mid)
            Push(Tree[id].leftSon, nodeL, mid, queryL, queryR, line);

        if (queryR > mid)
            Push(Tree[id].rightSon, mid + 1, nodeR, queryL, queryR, line);
    }

    valueType Query(valueType id, valueType nodeL, valueType nodeR, valueType x) {
        if (id == -1)
            return MIN;

        if (nodeL == nodeR)
            return Tree[id].data(x);

        valueType const mid = (nodeL + nodeR) >> 1;

        if (x <= mid)
            return std::max(Tree[id].data(x), Query(Tree[id].leftSon, nodeL, mid, x));
        else
            return std::max(Tree[id].data(x), Query(Tree[id].rightSon, mid + 1, nodeR, x));
    }
};

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

#ifndef LOCAL_STDIO
    freopen("relics.in", "r", stdin);
    freopen("relics.out", "w", stdout);
#endif

    valueType N, M;

    std::cin >> N >> M;

    ValueVector A(N + 1);

    for (valueType i = 1; i <= N; ++i)
        std::cin >> A[i];

    TupleVector B;
    B.reserve(N);

    {
        ValueVector L(N + 1, N + 1), R(N + 1, 0);
        ValueStack stack;

        for (valueType i = 1; i <= N; ++i) {
            while (!stack.empty() && A[stack.top()] > A[i]) {
                R[stack.top()] = i;

                stack.pop();
            }

            stack.push(i);
        }

        while (!stack.empty()) {
            R[stack.top()] = N + 1;

            stack.pop();
        }

        for (valueType i = N; i >= 1; --i) {
            while (!stack.empty() && A[stack.top()] > A[i]) {
                L[stack.top()] = i;

                stack.pop();
            }

            stack.push(i);
        }

        while (!stack.empty()) {
            L[stack.top()] = 0;

            stack.pop();
        }

        for (valueType i = 1; i <= N; ++i)
            B.emplace_back(i, L[i] + 1, R[i] - 1, (R[i] - L[i] - 1) * A[i]);
    }

    ValueVector Ans(M);
    PairVector Querys(M);

    for (auto &[l, r] : Querys)
        std::cin >> l >> r;

    { // l <= a <= b <= r
        Tree tree(N);

        PairMatrix Nodes(N + 1);

        for (auto const &[i, l, r, w] : B)
            Nodes[r].emplace_back(l, w);

        PairMatrix Queue(N + 1);

        for (valueType i = 0; i < M; ++i) {
            auto const &[l, r] = Querys[i];

            Queue[r].emplace_back(l, i);
        }

        for (valueType r = 1; r <= N; ++r) {
            for (auto const &[l, w] : Nodes[r])
                tree.Modify(l, w);

            for (auto const &[l, id] : Queue[r])
                Ans[id] = std::max(Ans[id], tree.Query(l, r));
        }
    }

    { // a <= l <= r <= b
        Tree tree(N);

        PairMatrix Nodes(N + 1);

        for (auto const &[i, l, r, w] : B)
            Nodes[r].emplace_back(l, A[i]);

        PairMatrix Queue(N + 1);

        for (valueType i = 0; i < M; ++i) {
            auto const &[l, r] = Querys[i];

            Queue[r].emplace_back(l, i);
        }

        for (valueType r = N; r >= 1; --r) {
            for (auto const &[l, w] : Nodes[r])
                tree.Modify(l, w);

            for (auto const &[l, id] : Queue[r])
                Ans[id] = std::max(Ans[id], tree.Query(1, l) * (r - l + 1));
        }
    }

    { // a <= l <= b <= r
        LiChaoTree tree(N);

        ValueMatrix Nodes(N + 1);

        for (valueType id = 0; id < N; ++id) {
            auto const &[i, l, r, w] = B[id];

            Nodes[r].push_back(id);
        }

        PairMatrix Queue(N + 1);

        for (valueType i = 0; i < M; ++i) {
            auto const &[l, r] = Querys[i];

            Queue[r].emplace_back(l, i);
        }

        for (valueType r = 1; r <= N; ++r) {
            for (auto const &id : Nodes[r]) {
                auto const &[i, l, r, w] = B[id];

                tree.Push(l, r, -A[i], (r + 1) * A[i]);
            }

            for (auto const &[l, id] : Queue[r])
                Ans[id] = std::max(Ans[id], tree.Query(l));
        }
    }

    { // l <= a <= r <= b
        LiChaoTree tree(N);

        ValueMatrix Nodes(N + 1);

        for (valueType id = 0; id < N; ++id) {
            auto const &[i, l, r, w] = B[id];

            Nodes[l].push_back(id);
        }

        PairMatrix Queue(N + 1);

        for (valueType i = 0; i < M; ++i) {
            auto const &[l, r] = Querys[i];

            Queue[l].emplace_back(r, i);
        }

        for (valueType l = N; l >= 1; --l) {
            for (auto const &id : Nodes[l]) {
                auto const &[i, l, r, w] = B[id];

                tree.Push(l, r, A[i], -(l - 1) * A[i]);
            }

            for (auto const &[r, id] : Queue[l])
                Ans[id] = std::max(Ans[id], tree.Query(r));
        }
    }

    for (auto const &x : Ans)
        std::cout << x << '\n';

    std::cout << std::flush;

    return 0;
}

C. 吞天得手

考虑如下自动机:每个节点代表了一个本质不同的子序列。从起始状态到达某个节点的转移边字符顺次连接即可得到该节点所代表的子序列。

那么我们只需要在该自动机上遍历出字典序前 \(k\) 小的路径即可。

考虑如何建出自动机,不妨将其转化为对于某个节点,找到其出边集合以及出边可以到达的节点所代表的子序列在原序列中的出现次数。因此我们可以将转移边视作对现有序列的扩展。

设我们现在已经得到了一种子序列 \(s\),为了按字典序遍历子序列,我们可以从小到大枚举其末尾新增的元素。

考虑在确定新增元素后如何计算方案数。发现对于新增元素在原序列的每次出现的位置,其贡献系数取决于在其之前有多少个完整出现的子序列 \(s\)。因此这启示我们对于每种子序列维护其末尾元素的出现位置集合和每个位置对应的方案数。进而设当前位置集合中最早的位置 \(x\),那么 \(a[x + 1, n]\) 中的元素均可在扩展在当前子序列 \(s\) 末尾。不妨从小到大枚举其,设当前枚举到的元素为 \(v\),那么扩展后的状态的位置集合即为 \(v\) 在 \(a[x + 1, n]\) 中的所有出现位置组成的集合。而新的位置集合每个位置对应的方案数为原来子序列 \(s\) 对应的位置集合中所有比其出现早的位置的方案数之和。

在遍历自动机的同时维护子序列哈希值即可。复杂度为 \(\mathcal{O}(n\log n + k \log n)\)。

Code
#include <bits/stdc++.h>

typedef long long valueType;
typedef std::vector<valueType> ValueVector;
typedef std::vector<ValueVector> ValueMatrix;
typedef std::pair<valueType, valueType> ValuePair;
typedef std::vector<ValuePair> PairVector;
typedef std::vector<PairVector> PairMatrix;
typedef std::tuple<ValuePair, valueType, valueType> DataTuple;
typedef std::priority_queue<DataTuple, std::vector<DataTuple>, std::greater<>> MinDataHeap;
typedef std::vector<MinDataHeap> MinDataHeapMatrix;

namespace MODINT {
    constexpr valueType MOD = 998244353;

    template<typename T1, typename T2>
    T1 sum(T1 a, T2 b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }

    template<typename T1, typename T2>
    T1 sub(T1 a, T2 b) {
        return a - b < 0 ? a - b + MOD : a - b;
    }

    template<typename T1, typename T2>
    void Inc(T1 &a, T2 b) {
        a += b;

        if (a >= MOD)
            a -= MOD;
    }

    template<typename T1, typename T2>
    void Dec(T1 &a, T2 b) {
        a -= b;

        if (a < 0)
            a += MOD;
    }

    template<typename T1, typename T2>
    T1 mul(T1 a, T2 b) {
        return (long long) a * b % MOD;
    }

    template<typename T1, typename T2>
    void Mul(T1 &a, T2 b) {
        a = (long long) a * b % MOD;
    }

    template<typename T1, typename T2>
    T1 pow(T1 a, T2 b) {
        T1 result = 1;

        while (b > 0) {
            if (b & 1)
                Mul(result, a);

            Mul(a, a);
            b = b >> 1;
        }

        return result;
    }
} // namespace MODINT

using namespace MODINT;

template<typename T, class Compare_ = std::less<>>
class SparseTable {
private:
    valueType N, K;
    std::vector<std::vector<T>> data;

public:
    SparseTable() = default;

    explicit SparseTable(valueType n, std::vector<T> const &source) : N(n), K(std::__lg(N)), data(K + 1, std::vector<T>(N + 1)) {
        for (valueType i = 1; i <= N; ++i)
            data[0][i] = source[i];

        for (valueType k = 1; k <= K; ++k) {
            for (valueType i = 1; i + (1 << k) - 1 <= N; ++i)
                data[k][i] = std::min(data[k - 1][i], data[k - 1][i + (1 << (k - 1))], Compare_());
        }
    }

    T Query(valueType l, valueType r) const {
        valueType const len = r - l + 1;

        valueType const k = std::__lg(len);

        return std::min(data[k][l], data[k][r - (1 << k) + 1], Compare_());
    }
};

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

#ifndef LOCAL_STDIO
    freopen("ttds.in", "r", stdin);
    freopen("ttds.out", "w", stdout);
#endif

    valueType N, K, B;

    std::cin >> N >> K >> B;

    PairVector A(N + 1);

    for (valueType i = 1; i <= N; ++i) {
        std::cin >> A[i].first;

        A[i].second = i;
    }

    valueType const InvB = pow(B, MOD - 2);

    SparseTable<ValuePair, std::less<>> const ST(N, A);
    MinDataHeapMatrix Queue(N + 1);

    auto Flush = [&](valueType n) -> void {
        MinDataHeap().swap(Queue[n]);

        if (n < N)
            Queue[n].emplace(ST.Query(n + 1, N), n + 1, N); // weight, l, r
    };

    auto Get = [&](valueType n) -> ValueVector {
        if (Queue[n].empty())
            return ValueVector();

        ValueVector result;
        valueType const V = std::get<0>(Queue[n].top()).first;

        while (!Queue[n].empty()) {
            auto const [w, l, r] = Queue[n].top();

            if (w.first != V)
                break;

            Queue[n].pop();

            valueType const x = w.second;

            result.push_back(x);

            if (l < x)
                Queue[n].emplace(ST.Query(l, x - 1), l, x - 1);

            if (x < r)
                Queue[n].emplace(ST.Query(x + 1, r), x + 1, r);
        }

        return result;
    };

    ValueVector Ans;
    valueType now = 0;
    ValueVector Prefix;

    auto PushBack = [&](valueType x) -> valueType {
        Prefix.push_back(x);

        Mul(now, B);
        Inc(now, x);

        return now;
    };

    auto PopBack = [&]() -> valueType {
        valueType const x = Prefix.back();

        Prefix.pop_back();

        Dec(now, x);
        Mul(now, InvB);

        return now;
    };

    auto Solve = [&](auto self, PairVector const &S) -> void {
        if (Ans.size() >= K)
            return;

        valueType count = 0;

        for (auto const &[pos, w] : S)
            if (pos >= 1)
                count += w;

        Ans.insert(Ans.end(), count, now);

        Flush(S.front().first);

        while (Ans.size() < K) {
            ValueVector const NextPos = Get(S.front().first);

            if (NextPos.empty())
                return;

            PairVector Next;

            for (auto const &x : NextPos) {
                valueType sum = 0;

                for (auto const &[y, w] : S) {
                    if (y < x)
                        sum += w;
                    else
                        break;
                }

                Next.emplace_back(x, sum);
            }

            valueType const v = A[NextPos.front()].first;

            PushBack(v);

            self(self, Next);

            PopBack();
        }
    };

    PairVector Start({ValuePair(0, 1)});

    Solve(Solve, Start);

    Ans.resize(K);

    for (auto const &x : Ans)
        std::cout << x << '\n';

    std::cout << std::flush;

    return 0;
}

标签:std,2024.2,Set,15,auto,valueType,typedef,const,id
From: https://www.cnblogs.com/User-Unauthorized/p/-/2024-2-15

相关文章

  • 2024.2.15 模拟赛
    省流:rk41/58,被吊打了。别问我为什么题面没LaTeX,问就是懒。T1你现在有nn个数{ai}{ai​},现在他会对这些数做一些神秘的操作,规则如下:首先他会随便取出两个数aiai​和ajaj​(i≠j)(i=j).如果aiai​和ajaj​奇偶性相同,可以将aiai​和ajaj​合并成ai−ajai​......
  • 2024.2.15模拟赛总结
    这次发挥很好啊,rank1,300pts,比rank2高了70ptsT1发现操作二的影响是不可避免的,就尽可能让操作1没影响,每次就删连续的相同的数字,然后统计一下即可T2感觉思路很自然,首先只需要保留近k次操作如果有一个横的和一个竖的覆盖两个点,就可以直接走曼哈顿距离如果两点之间被横或......
  • 海亮02/15杂题
    海亮02/15杂题个人题单T2link题意给定一个\(n\)个点,\(m\)条边的仙人掌,每条边至多存在于一个环。你可以进行如下操作:选择一个度数为奇数的点,把与其相连的边全部删去。创建一个新的图,新图有\(2n\)个点。假如原图的编号为\(1\simn\),则若原图中\(u,v\)有边,则新图中......
  • 南外集训 2024.2.15 T3
    题目描述还能有错的?\(T\)组询问,每次给定\(n,k\),问:如果一个\(2n\)个数的排列所有偶数位置构成的子序列是单调递增的,那么说这个排列是好的。将一个好的排列按照顺序拆分成若干组,每一组个数都是偶数,形成的结构叫做一个城市。一个城市的价值是每个组内部的逆序对个数的乘积。求......
  • Python笔记09——Set(集合)
    九、集合9.1基础集合(set)是一个无序的不重复元素序列,可进行交、集、差等常见的集合操作。与序列的区别:无序,每次输出顺序随机;元素不重复;创建格式:parame={value01,value02,...}或者set(value)(创建空集合只能用set())创建集合示例set1={1,2,3,4}#直接使用......
  • Delete a node from bst【2月15日学习笔记】
    点击查看代码//Deleteanodefrombst#include<iostream>structnode{intdata;node*left;node*right;};node*getnewnode(intx){node*temp=newnode;temp->data=x;temp->left=temp->right=NULL;returntem......
  • 2.15随笔
    今天学习到了一个关于dp的小技巧,我就叫它“加维”了。当发现无论怎么列状态转移方程,都会存在变量时,就可以尝试加维,扩展一个变量的更新。例如bicycles这道题,它相比其他的图论多了一个可以更换自行车,导致无论怎么写传统的dij都无法更新自行车的变更,因此我们就可以加维,来能够更新自......
  • 20240215打卡
    使用MPAndroidChart第三方框架绘制柱状图:1.**在build.gradle文件中添加依赖项**(低版本可以导入jar包):打开您的项目的build.gradle文件,然后在dependencies部分添加MPAndroidChart的依赖项。```groovydependencies{implementation'com.github.PhilJay:MPAndroidCh......
  • 2023.2.15 LGJ Round
    A\(n\)个点,有\(m\)种操作\((w,l,r)\),代表贡献是\(w\),并消除\([l,r]\)的所有点。操作的条件是必须消除一个点,问最多的贡献是多少。\(n,m\le300\).考虑从小区间开始操作,不难联想到区间dp。\(dp_{i,j}\)代表\([l,r]\)都被消除的最大贡献。对于\(dp_{i,j}\),我们枚举......
  • 2024.2.14 WC24 线段树 / CF1572D / lgP3679
    西安Day1。感冒还没好,牙龈炎也没好,明天还要考试,又要坐牢了/kk。今天是tyy的图论选讲,感觉前面网络流部分还是在线的,平面图部分毒瘤tyy拿出了他的员交课件,恐怖,直接下线了。看了NAVI和Faze的预选赛,你们俩怎么都打的这么稀碎/fn。Override真好听。「WC2024」线段树我......