珂朵莉树

简介
珂朵莉树一般多见于区间推平操作,即把[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;
}
posted @ 2024-01-26 13:53  WandW  阅读(36)  评论(0)    收藏  举报