ODT 学习笔记

新年计划之学习 ODT \(\sim\) 完成!

Chtholly

超大图(

中国珂学院

ODT 又称珂朵莉树,起源于 Codeforces Round #449 (Div. 1) 的 C 题 Willem, Chtholly and Seniorious

ODT 是什么?

暴力数据结构。

例题

例题:CF896C,即上面那道题。

  1. 区间加
  2. 区间赋值
  3. 区间第 \(k\)
  4. 求区间幂次和

初始化

struct node{
    int l, r;
    mutable int x;
    bool operator <(const node& T) const
    {return l<T.l;}
    node(int L, int R=-1, int X=0):l(L),r(R),x(X){}
};

表示 \(\forall i\in[l,r]\and i\in \mathbb{N^+},a_i=x\)

mutable 是因为要在 set 中修改。

核心操作 split

\([l,r]\) 分裂成 \([l,p)\)\([p,r]\)。(有一部分需要修改,另一部分不需要)

auto split(int pos){
    auto it=s.lower_bound(node(pos));
    if(it!=s.end()&&it->l==pos) return it;
    --it;
    int itl=it->l, itr=it->r;
    ll itx=it->x;
    s.erase(it);
    s.insert(node(itl,pos-1,itx));
    return s.insert(node(pos,itr,itx)).first;
}

推平操作 assign

即区间赋值。

\([l,r]\) 之间的数删除,并赋上一个数。(将多个点变成一个点,大大减少时间复杂度)

事实证明 assign 的操作次数可占到总操作次数的 \(\dfrac14\),将节点数优化到 \(\log\) 级别。

auto assign(int l, int r, ll x){
    auto itr=split(r+1), itl=split(l);
    s.erase(itl,itr);
    s.insert(node(l,r,x));
}

记得一定要先 split(r+1)split(l),因为如果先 split(l),返回的迭代器会位于所对应的区间以 \(l\) 为左端点,此时如果 \(r\) 也在这个节点内,就会导致 split(l) 返回的迭代器被 erase 掉,导致 \(\tt\color{purple}{RE}\)

其他操作

暴力即可。

void add(int l, int r, ll delta){
    auto itr=split(r+1), itl=split(l);
    for(auto it=itl;it!=itr;++it)
        it->x+=delta;
}
ll kth(int l, int r, int k){
    auto itr=split(r+1), itl=split(l);
    vector<pair<ll,int>> vec;
    for(auto it=itl;it!=itr;++it)
        vec.push_back(make_pair(it->x,it->r-it->l+1));
    sort(vec.begin(),vec.end());
    for(auto it:vec){
        k-=it.second;
        if(k<=0) return it.first;
    }
}
ll qpow(ll a, int b, ll mod){
    ll res=1ll;
    a%=mod;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll query(int l, int r, int ind, ll mod){
    auto itr=split(r+1), itl=split(l);
    ll res=0ll;
    for(auto it=itl;it!=itr;++it)
        res=(res+(it->r-it->l+1)*qpow(it->x,ind,mod)%mod)%mod;
    return res;
}

ODT 固然好用,但容易被卡 /kk

适合当暴力骗分 /cy

posted @ 2022-02-09 17:13  int32  阅读(86)  评论(0)    收藏  举报