珂朵莉树模板(ODT)

Posted zhuyou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了珂朵莉树模板(ODT)相关的知识,希望对你有一定的参考价值。

解决区间赋值 + 区间(k)次方和(数据随机)

#include<bits/stdc++.h>
#define IT set<Node>::iterator
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;

struct Node{
    int l, r;
    mutable ll v;
    bool operator < (const Node &p) const{
        return l < p.l;
    }
};
set<Node> s;

IT split(int pos){
    IT it = s.lower_bound(Node{pos,pos,0});
    if(it != s.end() && it->l == pos) return it;
    it--;
    int l = it->l, r = it->r;
    ll v = it->v;
    s.erase(it);
    s.insert(Node{l, pos-1, v});
    return s.insert(Node{pos, r, v}).first;
}
//split要先r+1, 再l
void update(int l, int r, ll v){
    IT rit = split(r+1), lit = split(l);
    s.erase(lit, rit);
    s.insert(Node{l, r, v});
}

ll fpow(ll a, ll b){
    ll ans = 1;
    while(b){
        if(b &1)
            ans = ans * a % mod;
        a = a * a % mod;
        b /= 2;
    }
    return ans;
}

ll query(int l, int r, ll k){
    IT rit = split(r+1), lit = split(l);
    ll ans = 0;
    for(; lit != rit;lit++)
        ans += fpow(lit->v, k) * 1ll * (lit->r - lit->l);
    return ans;
}

int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    s.insert(Node{1, n, 0ll});
    int id, l, r;
    ll x;
    while(m--){
        scanf("%d%d%d%lld", &id, &l, &r, &x);
        if(id == 1)
            update(l, r, x);
        else
            printf("%lld
", query(l, r, x));
    }
}

以上是关于珂朵莉树模板(ODT)的主要内容,如果未能解决你的问题,请参考以下文章

[Codeforces896C] Willem, Chtholly and Seniorious (ODT-珂朵莉树)

ODT (Old Driver Tree)珂朵莉树

毒瘤数据结构之珂朵莉树

模板—珂朵莉树

P2787 语文1(chin1)- 理理思维(珂朵莉树)

CF896C Willem, Chtholly and Seniorious 珂朵莉树