首页 > 其他分享 >珂朵莉树

珂朵莉树

时间:2024-01-26 13:55:36浏览次数:26  
标签:node set int pos 朵莉树 split tol

简介
珂朵莉树一般多见于区间推平操作,即把[l,r]区间的值都赋值成k值的区间推平操作,在数据随机中可以出现奇效。
模板

点击查看代码
struct node
{
    int l,r;
    mutable int v;//mutable相反于const 用于操作存于set(存于set的均为const,但是加了mutable即可修改其值)中的值.
    node(int i,int j,int k):l(i),r(j),v(k)
    {

    };
    operator <(const node &o)const
    {
        return l<o.l;   //重定义小于运算符,用于给set进行排序

    }

};
set<node>s;
set<node>::iterator split(int pos)
{
    set<node>::iterator it=s.lower_bound(node(pos,0,0));//set库当中的lower_bound()和upper_bound() 
                                                        //是返回>=参数val或>参数val的迭代器;
    if(it!=s.end()&&it->l==pos)
    {
        return it;
    }
    it--;
    int l=it->l,r=it->r,v=it->v;
    s.erase(it);
    s.insert(node(l,pos-1,v));
    return s.insert(node(pos,r,v)).first;
}
void assign(int l,int r,int k)
{
    auto itr=split(r+1),itl=split(l);//split函数是返回split(pos)中以pos为左边界的迭代器
    int len=0,tol=0;                 //set的erase操作中左闭右开,即删除包含左迭代器到不包含右迭代器的中间部分     
    for(auto i=itl;i!=itr;i++)
    {
        len+=i->r-i->l+1;
        tol+=i->v*(i->r-i->l+1);
    }
    s.erase(itl,itr);
    s.insert(node(l,r,k));
    if(k==0)
    {
       sum-=tol;

    }
    else
    {
       sum+=len-tol;

    }
}

1.CF915E
思路:
用珂朵莉树给左右端点赋值,进行区间推平操作。

点击查看代码
#include<iostream>
#include<vector>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define ll long long
int sum;
struct node
{
    int l,r;
    mutable int v;
    node(int i,int j,int k):l(i),r(j),v(k)
    {

    };
    operator <(const node &o)const
    {
        return l<o.l;

    }

};
set<node>s;
set<node>::iterator split(int pos)
{
    set<node>::iterator it=s.lower_bound(node(pos,0,0));
    if(it!=s.end()&&it->l==pos)
    {
        return it;
    }
    it--;
    int l=it->l,r=it->r,v=it->v;
    s.erase(it);
    s.insert(node(l,pos-1,v));
    return s.insert(node(pos,r,v)).first;
}
void assign(int l,int r,int k)
{
    auto itr=split(r+1),itl=split(l);//split函数是返回split(pos)中以pos为左边界的迭代器
    int len=0,tol=0;                 //set的erase操作中左闭右开,即删除包含左迭代器到不包含右迭代器的中间部分     
    for(auto i=itl;i!=itr;i++)
    {
        len+=i->r-i->l+1;
        tol+=i->v*(i->r-i->l+1);
    }
    s.erase(itl,itr);
    s.insert(node(l,r,k));
    if(k==0)
    {
       sum-=tol;

    }
    else
    {
       sum+=len-tol;

    }
}
signed main()
{
     cin.tie(NULL);
     cout.tie(nullptr);
     ios_base::sync_with_stdio(false);
     int n;
     int q;
     cin>>n>>q;
     s.insert(node(1,n,1));
     sum=n;
    for(int i=1;i<=q;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        assign(a,b,c==1?0:1);
        cout<<sum<<'\n';
    }
     return 0;
}

标签:node,set,int,pos,朵莉树,split,tol
From: https://www.cnblogs.com/wner/p/17989171

相关文章

  • [学习笔记]珂朵莉树
    目录0x00:介绍1x00:思想1x01:节点保存1x02:核心操作split1x03:推平操作assign2x00:例题2x01:CF896C2x02:CF915E3x00:总结0x00介绍珂朵莉树(ChthollyTree),又称ODT(OldDriverTree),一种数据结构,但似乎暴力到不能称之为数据结构。可以很好地骗分,在随机数据下十分有效,常用于将\([l......
  • 珂朵莉树
    珂朵莉树的适用范围是具有区间赋值操作且数据随机的题目。珂朵莉树的思想在于随机数据下的区间赋值操作很可能让大量元素变为同一个数,所以我们以三元组<l,r,v>的形式保存数据(区间[l,r]中的元素的值都是v):structnode{lll,r;mutablellv;//这里mutable要写不然......
  • 柯学家——珂朵莉树 学习笔记
    柯学家——珂朵莉树学习笔记珂朵莉树(ChthollyTree),又名老司机树ODT(OldDriverTree)。起源自lxl的CF896CWillem,ChthollyandSeniorious。前置知识:std::set。思想将区间用set维护,每次对一个区间进行操作的时候,就将这个区间分离(split)出来。复杂度的保证依靠推平......
  • 颜色段均摊(珂朵莉树)
    珂朵莉树的复杂度分析CF896C珂朵莉树起源题LG4979矿洞:坍塌珂朵莉树可以在区间覆盖时顺便把左右的同色段合并了,这样任意时刻相邻的两段都不同色本题询问时判断\([l,r]\)是否同色就可以通过判断\([l,r]\)是否在同一段实现了https://www.luogu.com.cn/problem/P8146......
  • 珂朵莉树——优雅的暴力
    珂朵莉树引入珂朵莉树(ChthollyTree),又名老司机树(OldDriverTree)。起源于CF896C。这种想法的本质是基于数据随机的「颜色段均摊」,而不是一种数据结构。前置需要了解STL的set的基本用法。比如:insert(x) 当容器中没有等价元素的时候,将元素x插入到 set 中。er......
  • 珂朵莉树(ODT)
    处理区间赋值问题的神器!珂朵莉树的实现非常简单(baoli),建树时把区间的左右端点和权值作为一个节点全扔到std::set(或者链表)中维护即可split:核心操作之一,将一段区间提取出来,在此之上进行一些操作assign:核心操作之二,也是降低珂朵莉树时间复杂度的重要操作,把一段区间推平赋值,......
  • 珂朵莉树
    区间赋值的数据结构都可以骗分,在数据随机的情况下,复杂度可以保证。时间复杂度: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 | 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\));......