珂朵莉树学习笔记
珂朵莉树学习笔记
其实是暴力学习笔记
珂朵莉树(Chtholly Tree),又名老司机树 ODT(Old Driver Tree)。起源自 CF896C。
- 原理:暴力
- 用途:骗分,在有区间赋值的情况下,如果数据随机完全可以当正解打。
正文
前置知识: \(std::set\)
思路:用\(set\)或者\(map\)维护区间的信息,本人用的是\(set\)。
左端点排序维护区间
以CF896C为例
-
存结构体
直接看代码吧
\(code:\)
struct node{ int l,r; mutable ll val; bool operator < (const node &a) const {return l < a.l;} node(int L = 0,int R = 0,ll Val = 0): l(L),r(R),val(Val){} }; set<node> s; #define sit set<node>::iterator
其中 \(mutable\) 的用处是让我们可以直接在 \(set\) 中改变 \(val\) 的值
-
建树
将需要的区间直接插入\(code:\)
for(int i = 1;i <= n; ++i) T.insert(i,i,a[i]);
-
核心操作:
-
\(split\)
作用:将区间 \([l,r]\) 分裂成 \([l,pos)\) 和 \([pos,r]\) 并返回 \([pos,r]\) 的迭代器
\(code:\)
inline sit split(int pos){ sit it = s.lower_bound(node(pos));//先查找pos所在区间 if(it != s.end() && it->l == pos) return it;//如果已经分好了直接返回即可 -- it;//否则一定在上一个区间里 int l = it->l,r = it->r,val = it->val;//存一下 s.erase(it);//删除原区间 s.insert(node(l,pos-1,val));//插入[l,pos) return s.insert(node(pos,r,val)).first;//插入[pos,r]并返回所在迭代器 //因为insert的返回值类型为pair<set<typename>::iterator,bool> //typename为类型名 }
\(tips:\)珂朵莉树在进行求取区间左右端点操作时,必须先 \(split\) 右端点,再 \(split\) 左端点。若先 \(split\) 左端点,返回的迭代器可能在 \(split\) 右端点的时候失效,可能会导致 RE。
-
\(assign\)
高贵的区间推平,保证珂朵莉树复杂度的核心操作。
\(code:\)
inline void assign(int l,int r,ll val){ sit it2 = split(r+1),it1 = split(l);//分裂区间 s.erase(it1,it2);//将[it1,it2)从set中删去 s.insert(node(l,r,val));//插入新的元素 }
-
-
其他操作
暴力即可区间加:
inline void add(int l,int r,ll val){ sit it2 = split(r+1),it1 = split(l); for(sit i = it1;i != it2; ++i) i->val += val; }
区间第k大值:
inline ll kth(int l,int r,int k){ vector<pair<ll,int> > res; sit it2 = split(r+1),it1 = split(l); for(sit i = it1;i != it2; ++i) res.emplace_back(make_pair(i->val,i->r - i->l +1)); sort(res.begin(),res.end()); for(auto i : res){ k -= i.second; if(k <= 0) return i.first; } return 0; }
区间幂次和:
inline ll pow_sum(int l,int r,int x,int mod){ sit it2 = split(r+1),it1 = split(l); ll res = 0; for(sit i = it1;i != it2; ++i) res = (res+1ll*(i->r - i->l +1)*power(i->val,x,mod)%mod)%mod; return res; }
-
复杂度分析(不会啊太难了看这个吧)
-
例题:
骗分的暴力还有什么例题
update on 2024-7-29
今天模拟赛考了一道,但我没推出可以用这个东西维护,一直在想bitset了
挂一下原题链接,可以当一道ODT的例题
__________________________________________________________________________________________
本文来自博客园,作者:CuFeO4,转载请注明原文链接:https://www.cnblogs.com/hzoi-Cu/p/18212045