第 446 场周赛——求出数组的 X 值 II

题目

求出数组的 X 值 II

题解

用到线段树确实忘完了,这里用的是灵神的板子,只需要根据题意修改即可。

参考代码

class SegmentTree { //线段树板子
    using T = pair<int, array<int, 5>>;     //这里可以template<typename T>在一开始定义,也可以这样在这里定义

    int k;
    int n;
    vector<T> tree;

    T merge_val(T a, T b) const{    //合并两个val,视题目而改变
        auto [left_mul, cnt] = a;
        for(int rx = 0; rx < k; rx++) {
            cnt[left_mul * rx % k] += b.second[rx];
        }
        return {left_mul * b.first % k, cnt};
    }

    T new_val(int val) const {  //更新单个节点
        int mul = val % k;
        array<int, 5> cnt{};
        cnt[mul] = 1;
        return {mul, cnt};
    }

    void maintain(int node) {   //合并左右儿子的val到当前节点
        tree[node] = merge_val(tree[node * 2], tree[node * 2 + 1]);
    }

    void build(const vector<int>& a, int node, int l, int r) {  //初始化线段树
        if(l == r) {
            tree[node] = new_val(a[l]);
            return;
        }
        int m = (l + r) / 2;
        build(a, node * 2, l, m);
        build(a, node * 2 + 1, m + 1, r);
        maintain(node);
    }

    void update(int node, int l, int r, int i, int val) {   //更新线段树中某个元素的值
        if(l == r) {
            tree[node] = new_val(val);
            return;
        }
        int m = (l + r) / 2;
        if(i <= m) {
            update(node * 2, l, m, i, val);
        } else {
            update(node * 2 + 1, m + 1, r, i, val);
        }
        maintain(node);
    }

    T query(int node, int l, int r, int ql, int qr) const {     
        if(ql <= l && r <= qr) {
            return tree[node];
        }
        int m = (l + r) / 2;
        if(qr <= m) {
            return query(node * 2, l, m, ql, qr);
        } 
        if(ql > m) {
            return query(node * 2 + 1, m + 1, r, ql, qr);
        }
        T l_res = query(node * 2, l, m, ql, qr);
        T r_res = query(node * 2 + 1, m + 1, r, ql, qr);
        return merge_val(l_res, r_res);
    }
public:
    SegmentTree(const vector<int>& a, int k) : k(k), n(a.size()), tree(2 << bit_width(a.size() - 1)) {  //:后面为初始化的内容
        build(a, 1, 0, n - 1);
    }

    void update(int i, int val) {
        update(1, 0, n - 1, i, val);
    }

    T query(int ql, int qr) const {
        return query(1, 0, n - 1, ql, qr);
    }
};

class Solution {
public:
    vector<int> resultArray(vector<int>& nums, int k, vector<vector<int>>& queries) {
        SegmentTree t(nums, k);
        int n = nums.size();
        vector<int> ans;
        for(auto& q : queries) {
            t.update(q[0], q[1]);
            auto [_, cnt] = t.query(q[2], n - 1);
            ans.push_back(cnt[q[3]]);
        }
        return ans;
    }
};
posted @ 2025-04-24 20:41  PZnwbh  阅读(8)  评论(0)    收藏  举报