萌新 MLE 求助
查看原帖
萌新 MLE 求助
610557
shinzanmonoszm 妹妹楼主2022/12/30 20:11
#include<iostream>
#include<algorithm>
#include<limits>
#include<set>
#include<map>
#include<stack>
const int sz = 3e5 + 10;
const int inf = std::numeric_limits<int>::max();
std::map<int, int> dict;
std::stack<int> candidate;
std::set<int> exists[sz];
int arr[sz], carr[sz], prevarr[sz], cnt;
struct ST {
    struct node {
        int prevmax, carrmax, carrmin, gcd;
        node operator+(const node &a) const {
            return node {
                std::max(prevmax, a.prevmax),
                std::max(carrmax, a.carrmax),
                std::min(carrmin, a.carrmin),
                std::__gcd(gcd, a.gcd)
            };
        }
    } tree[sz << 2];
    void build(int p, int ln, int rn) {
        if (ln == rn) return tree[p] = node{prevarr[ln], carr[ln], carr[ln], carr[ln]}, void();
        int mid = ln + rn >> 1;
        build(p << 1, ln, mid);
        build(p << 1 | 1, mid + 1, rn);
        tree[p] = tree[p << 1] + tree[p << 1 | 1];
    }
    void update(int p, int ln, int rn, int pos, int val, int prev) {
        if (ln == rn) return tree[p] = node{prev, val, val, val}, void();
        int mid = ln + rn >> 1;
        if (pos <= mid) update(p << 1, ln, mid, pos, val, prev);
        if (pos > mid) update(p << 1 | 1, mid + 1, rn, pos, val, prev);
        tree[p] = tree[p << 1] + tree[p << 1 | 1];
    }
    node query(int p, int ln, int rn, int l, int r) {
        if (ln >= l && rn <= r) return tree[p];
        int mid = ln + rn >> 1;
        node res = {-inf, -inf, inf, 0};
        if (ln <= mid) res = res + query(p << 1, ln, mid, l, r);
        if (rn > mid) res = res + query(p << 1 | 1, mid + 1, rn, l, r);
        return res;
    }
} st;
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n, q;
    std::cin >> n >> q;
    for (int i = 1; i <= n; i++) {
        std::cin >> arr[i];
        carr[i] = arr[i];
        if (dict.find(arr[i]) == dict.end()) {
            dict[arr[i]] = ++cnt;
            exists[cnt].insert(0);
        }
        arr[i] = dict[arr[i]];
        prevarr[i] = *exists[arr[i]].rbegin();
        exists[arr[i]].insert(i);
    }
    ST::node res;
    std::set<int>::iterator it;
    int num = 0;
    while (q--) {
        int op, l, r, u, v, k;
        std::cin >> op;
        if (op == 1) {
            std::cin >> u >> v;
            u ^= num, v ^= num;
            it = exists[arr[u]].find(u);
            ++it;
            if (it == exists[arr[u]].end()) {
                prevarr[*it] = prevarr[u];
                st.update(1, 1, n, *it, carr[*it], prevarr[*it]);
            }
            --it;
            exists[arr[u]].erase(it);
            if (exists[arr[u]].size() == 1) {
                candidate.push(arr[u]);
                dict.erase(dict.find(carr[u]));
            }
            carr[u] = v;
            if (dict.find(v) == dict.end()) {
                if (candidate.empty()) {
                    dict[v] = ++cnt;
                    exists[cnt].insert(0);
                } else {
                    dict[v] = candidate.top();
                    candidate.pop();
                }
                v = dict[v];
            }
            arr[u] = v;
            it = exists[v].insert(u).first;
            --it;
            prevarr[u] = *it;
            std::advance(it, 2);
            if (it != exists[v].end()) {
                prevarr[*it] = u;
                st.update(1, 1, n, *it, carr[*it], prevarr[*it]);
            }
            st.update(1, 1, n, u, carr[u], prevarr[u]);
        } else {
            std::cin >> l >> r >> k;
            l ^= num, r ^= num, k ^= num;
            res = st.query(1, 1, n, l, r);
            if ((res.prevmax < l || !k) && res.carrmax - res.carrmin == k * (r - l) && (res.gcd == k || !res.gcd))
                std::cout << "Yes\n", num++;
            else std::cout << "No\n";
        }
    }
    return 0;
}

2022/12/30 20:11
加载中...