珂朵莉树map实现

文章目录

    • 可以解决的问题
    • 一个简单的例子(map实现)
    • 模板题 [896C — Willem, Chtholly and Seniorious](https://codeforces.com/contest/896/problem/C)

可以解决的问题

区间推平问题。将 [ l , r ] [l, r] [l,r]区间的值改为 x x x,随机数据下每次操作可认为是 O ( l o g N ) O(logN) O(logN),在只有区间推平操作的时候复杂度是正确的,其它的操作在区间推平的时候暴力做就可以了。

一个简单的例子(map实现)

个人认为map的实现会比set容易

将区间[l, r]的值改为v

我们首先使用一个map

map<int, int> mp;

mp[l]就表示[l, next[mp[l]])这一段区间的值是mp[l]

那么我们要做的就是将区间[l, r]切开,然后把map中所有下标小于等于r的全部删除,然后再令mp[l] = v即可

auto split = [&](int pos){ // 根据pos切开区间
    if(mp.find(pos) == mp.end())
        mp[pos] = prev(mp.lower_bound(pos)) -> second;
};
//接下来的操作就是将区间[l, r]删除并且令mp[l] = v
split(l), split(r + 1);
auto it = mp.find(l);
while(it -> first < r + 1){
    // 有时需要处理删除区间所造成的影响...
    it = mp.erase(it);
}
mp[l] = v;

模板题 896C — Willem, Chtholly and Seniorious

int seed;
int rng(){
    int ret = seed;
    seed = (seed * 7 + 13) % 1000000007;
    return ret;
}
int qmi(int a, int b, int p){
    int res = 1;
    while(b){
        if(b & 1) (res *= a) %= p;
        (a *= a) %= p;
        b >>= 1;
    }
    return res;
}
void solve() {
    map<int, int> mp;
    int n = read(), m = read();
    mp[0] = mp[n + 1] = -1;
    seed = read();
    int vm = read();
    vector<int> a(n + 1);
    rep(i, 1, n)
        a[i] = (rng() % vm) + 1;
    rep(i, 1, n)
        mp[i] = a[i];
    auto split = [&](int pos){
        if(mp.find(pos) == mp.end()){
            mp[pos] = prev(mp.upper_bound(pos)) -> second;
        }
    };
    while(m--){
        int op = (rng() % 4) + 1;
        int l = (rng() % n) + 1, r = (rng() % n) + 1;
        if(l > r) swap(l, r);
        int x;
        if(op == 3) x = rng() % (r - l + 1) + 1;
        else x = rng() % vm + 1;
        if(op == 1){
            split(l), split(r + 1);
            auto it = mp.find(l);
            while(it -> first < r + 1){
                it -> second += x;
                ++it;
            }
        }
        else if(op == 2){
            split(l), split(r + 1);
            auto it = mp.find(l);
            while(it -> first < r + 1){
                it = mp.erase(it);
            }
            mp[l] = x;
        }
        else if(op == 3){
            vector<array<int, 2>> vs;
            split(l), split(r + 1);
            auto it = mp.find(l);
            while(it -> first < r + 1){
                auto ne = next(it);
                vs.push_back({it -> second, ne -> first - it -> first});
                ++it;
            }
            sort(vs.begin(), vs.end());
            for(auto p : vs){
                if(x <= p[1]){wt(p[0]); break;}
                x -= p[1];
            }
        }
        else{
            int y = rng() % vm + 1;
            vector<array<int, 2>> vs;
            split(l), split(r + 1);
            auto it = mp.find(l);
            while(it -> first < r + 1){
                auto ne = next(it);
                vs.push_back({it -> second, ne -> first - it -> first});
                ++it;
            }
            int ans = 0;
            for(auto p : vs)
                (ans += p[1] * qmi(p[0] % y, x, y) % y) %= y;
     //       for(auto p : vs) cout << p[0] << ' ' << p[1] << '\n';
            wt(ans);
        }
    }
}

你可能感兴趣的:(算法)