首页 > 其他分享 >珂朵莉树(ODT)

珂朵莉树(ODT)

时间:2023-06-15 21:00:11浏览次数:42  
标签:int odt ODT ret 朵莉树 split it2 it1

处理区间赋值问题的神器!

珂朵莉树的实现非常简单(baoli),建树时把区间的左右端点和权值作为一个节点 全扔到std::set(或者链表)中维护即可

split: 核心操作之一,将一段区间提取出来,在此之上进行一些操作

assign: 核心操作之二,也是降低珂朵莉树时间复杂度的重要操作,把一段区间推平赋值,减少大量节点个数,防止其退化成暴力

其他操作就非常暴力的进行就可以了

在网上查珂朵莉的时间复杂度大概是 \(n \log \log\) 的,常数很小,在随机数据下吊打线段树

但是,很多毒瘤的出题人会卡珂朵莉树,让区间赋值操作尽可能的少,这样就寄了

以这道题为例 CF896C (珂朵莉树起源)

大体操作:区间加 区间修改 求区间第k小 求区间x次幂

$my\,\ code$
#include<bits/stdc++.h>
#define read(a) scanf("%lld",&a)
#define read4(a,b,c,d) scanf("%lld%lld%lld%lld",&a,&b,&c,&d)
#define write(a) printf("%lld\n",a)
#define mem(a) memset(a,0,sizeof(a));
#define debug() puts("qwq qwq qwq qwq qwq");
#define Chtholly set <node>::iterator
using namespace std;
constexpr int N(1e5+5);
#define int long long
int n,m,seed,vmax,a[N];
inline int rnd(){
    int ret=seed;
    seed=(seed*7+13)%1000000007;
    return ret;
}
inline void make_data(int &op,int &l,int &r,int &x,int &y){
    op=(rnd()%4)+1;l=(rnd()%n)+1;r=(rnd()%n)+1;
    if(l>r) swap(l,r);
    if(op==3) x=(rnd()%(r-l+1))+1;
    else x=(rnd()%vmax)+1;
    if(op==4) y=(rnd()%vmax)+1;
}
struct node{
    int l,r;mutable int v;
    node()=default;
    node(int L,int R=0,int V=0):l(L),r(R),v(V){}
    bool operator<(const node &x)const{return l<x.l;}
};
set <node> odt;
Chtholly split(int pos){
    auto it=odt.lower_bound(pos);
    if(it!=odt.end()&&it->l==pos) return it;
    --it;if(it->r<pos) return odt.end(); 
	int l=it->l,r=it->r,v=it->v;
    odt.erase(it);odt.insert(node(l,pos-1,v));
    return odt.insert(node(pos,r,v)).first;
}
inline void assign(int l,int r,int v){
    auto it2=split(r+1),it1=split(l);
    odt.erase(it1,it2);
    odt.insert(node(l,r,v));
}
inline void add(int l,int r,int v){
    auto it2=split(r+1),it1=split(l);
    for(;it1!=it2;++it1){it1->v+=v;}
}
inline int kth(int l,int r,int k){
    auto it2=split(r+1),it1=split(l);
    vector <pair<int,int>> g;
    vector <pair<int,int>>().swap(g);
    for(;it1!=it2;++it1)
        g.push_back(make_pair(it1->v,it1->r-it1->l+1));
    sort(g.begin(),g.end());
    for(auto i:g){
        k-=i.second;
        if(k<=0) return i.first;
    }
    return -1;
}
inline int qpow(int a,int b,int p){
    int ret(1);a%=p;
    for(;b;a=a*a%p,b>>=1)
        if(b&1) ret=ret*a%p;
    return ret;
}
inline int sum(int l,int r,int x,int y){
    auto it2=split(r+1),it1=split(l);
    int ret(0);
    for(;it1!=it2;++it1)
        ret=(ret+qpow(it1->v,x,y)*(it1->r-it1->l+1)%y)%y;
    return ret;
}
signed main(){
    read4(n,m,seed,vmax);
    for(int i=1;i<=n;++i) a[i]=(rnd()%vmax)+1,odt.insert(node(i,i,a[i]));
    for(int i=1,op,l,r,x,y;i<=m;++i){
        make_data(op,l,r,x,y);
        switch(op){
            case 1:add(l,r,x);break;
            case 2:assign(l,r,x);break;
            case 3:write(kth(l,r,x));break;
            case 4:write(sum(l,r,x,y));break;
        } 
    }
    return 0;
}

标签:int,odt,ODT,ret,朵莉树,split,it2,it1
From: https://www.cnblogs.com/UNowen/p/17484100.html

相关文章

  • 珂朵莉树
    区间赋值的数据结构都可以骗分,在数据随机的情况下,复杂度可以保证。时间复杂度:O(nloglogn)structODT{ structnode{ intl,r; mutableLLv; node(intl,intr=-1,LLv=0):l(l),r(r),v(v){} booloperator<(constnode&o)const{returnl<o.l;} }; s......
  • ODT
    别写。Useless.TrysomeODT.CF915E\(\color{#52C41A}{\text{Accepted}}\)CF896C\(\color{#52C41A}{\text{Accepted}}\)P3740\(\color{#52C41A}{\text{Accepted}}\)......
  • 【模板】ODT | Old Driver Tree | 珂朵莉树
    postedon2021-04-0220:38:49|under学术|source这个东西本身不常用,但是这个维护连续段的写法很常用。标签:暴力、数据结构、std::set#include<set>template<cla......
  • 珂朵莉树学习笔记
    ##什么是珂朵莉树?**珂朵莉树**,别名颜色段均摊、ODT,它是$2017$年一场CF比赛中提出的数据结构,因为题目背景主角是《末日时在做什么?有没有空?可以来拯救吗?》的主角珂朵莉,......
  • 珂朵莉树浅析
    珂朵莉树浅析0.关于珂朵莉中国珂学院1.珂朵莉树实现珂朵莉树(也称OldDriverTree),是一种暴力数据结构,其代表的操作有:区间推平(将区间\([l,r]\)的数修改为\(x\));......
  • DDR3原理(ODT)
    一、存储器的分类存储器一般来说可以分为内部存储器(内存),外部存储器(外存),缓冲存储器(缓存)以及闪存这几个大类。内存也称为主存储器,位于系统主机板上,可以同CPU直接......
  • Microsoft 365 开发:如何通过脚本批量获取用户MFA状态以及Default MethodType
    Blog链接:​​​https://blog.51cto.com/13969817​​今天给大家分享一下如何通过脚本检验用户是否启用了MFA以及DefaultMethodType,首先我们确保环境:·      部署了MS......
  • 珂朵莉树
    严格来说,珂朵莉树主要的用处是骗分——OIWikiclassODT{structnode{intl,r;mutablellv;node(constint&il,constint&ir,......
  • 浅谈珂朵莉树
    珂朵莉最可爱了。好了不废话了,直接开始珂朵莉树。什么是珂朵莉树珂朵莉树,又叫老司机树,英文名字\(\text{ODT}\),是一种支持区间平推的乱搞数据结构,在数据随机时表现十分......
  • CDQ && 珂朵莉树
    对于题目:P4690[Ynoi2016]镜中的昆虫我们零基础从各个小部分开始学习,并且A了Ta.Part1CDQ分治一看到这个东西,一定会觉得很吓人,觉得是什么高大上的东西。其实不......