题目描述

分析

操作一、二、三为珂朵莉树的基本操作,操作四、五、六稍作转化即可

不会珂朵莉树请移步至这里

求和操作

把每一段区间分别取出,暴力相加

ll qh(ll l,ll r){
it2=Split(r+1),it1=Split(l);
ll ans=0;
for(it=it1;it!=it2;it++){
ans=(ans+(it->r-it->l+1)*it->val)%mod;
}
return ans;
}

赋值操作

直接调用\(Assign\)函数将其推平即可

void Assign(ll l,ll r,ll val){
it2=Split(r+1),it1=Split(l);
s.erase(it1,it2);
s.insert(asd(l,r,val));
}

修改操作

把每一段区间分别取出,暴力修改

void ad(ll l,ll r,ll val){
it2=Split(r+1),it1=Split(l);
for(it=it1;it!=it2;it++){
it->val+=val;
it->val%=mod;
}
}

复制操作

将区间\([l1,r1]\)中的元素取出记录一下,加入到区间\([l2,r2]\)中即可

void fz(ll l1,ll r1,ll l2,ll r2){
it2=Split(r1+1),it1=Split(l1);
for(tot=0,it=it1;it!=it2;it++){
a[++tot]=l2+it->l-l1,b[tot]=l2+it->r-l1,c[tot]=it->val;
}
for(ll i=1;i<=tot;++i){
Assign(a[i],b[i],c[i]);
}
}

交换操作

套用复制操作

我们可以先将区间\([l1,r1]\)复制到区间\([n+1,n+r1-l1+1]\)中

再将区间\([l2,r2]\)复制到区间\([l1,r1]\)中

最后再把区间\([n+1,n+r1-l1+1]\)复制到区间\([l2,r2]\)中

void jh(ll l1,ll r1,ll l2,ll r2) {
fz(l1,r1,n+1,n+r1-l1+1);
fz(l2,r2,l1,r1);
fz(n+1,n+r1-l1+1,l2,r2);
}

翻转操作

把区间中的数取出,再倒序加入

vector<asd> g;
void xz(ll l,ll r){
g.clear();
it2=Split(r+1),it1=Split(l);
aa=r;
for(it=it1;it!=it2;it++){
ll l=it->l,r=it->r,val=it->val;
g.push_back(asd(l,r,val));
}
s.erase(it1,it2);
for(ll i=0;i<g.size();i++){
s.insert(asd(aa-(g[i].r-g[i].l),aa,g[i].val));
aa-=(g[i].r-g[i].l+1);
}
}

完整代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
const ll mod=1e9+7;
ll a[maxn],b[maxn],c[maxn];
struct asd{
ll l,r;
mutable ll val;
bool operator < (const asd& A) const{
return l<A.l;
}
asd(ll aa,ll bb,ll cc){
l=aa,r=bb,val=cc;
}
asd(ll aa){
l=aa;
}
};
#define sit set<asd>::iterator
set<asd> s;
ll aa,bb,cc,dd,ee,n,m;
sit it,it1,it2;
sit Split(ll wz){
it=s.lower_bound(asd(wz));
if(it!=s.end() && it->l==wz) return it;
it--;
ll l=it->l,r=it->r,val=it->val;
s.erase(it);
s.insert(asd(l,wz-1,val));
return s.insert(asd(wz,r,val)).first;
}
ll qh(ll l,ll r){
it2=Split(r+1),it1=Split(l);
ll ans=0;
for(it=it1;it!=it2;it++){
ans=(ans+(it->r-it->l+1)*it->val)%mod;
}
return ans;
}
void Assign(ll l,ll r,ll val){
it2=Split(r+1),it1=Split(l);
s.erase(it1,it2);
s.insert(asd(l,r,val));
}
void ad(ll l,ll r,ll val){
it2=Split(r+1),it1=Split(l);
for(it=it1;it!=it2;it++){
it->val+=val;
it->val%=mod;
}
}
vector<asd> g;
void xz(ll l,ll r){
g.clear();
it2=Split(r+1),it1=Split(l);
aa=r;
for(it=it1;it!=it2;it++){
ll l=it->l,r=it->r,val=it->val;
g.push_back(asd(l,r,val));
}
s.erase(it1,it2);
for(ll i=0;i<g.size();i++){
s.insert(asd(aa-(g[i].r-g[i].l),aa,g[i].val));
aa-=(g[i].r-g[i].l+1);
}
}
int tot;
void fz(ll l1,ll r1,ll l2,ll r2){
it2=Split(r1+1),it1=Split(l1);
for(tot=0,it=it1;it!=it2;it++){
a[++tot]=l2+it->l-l1,b[tot]=l2+it->r-l1,c[tot]=it->val;
}
for(ll i=1;i<=tot;++i){
Assign(a[i],b[i],c[i]);
}
}
void jh(ll l1,ll r1,ll l2,ll r2) {
fz(l1,r1,n+1,n+r1-l1+1);
fz(l2,r2,l1,r1);
fz(n+1,n+r1-l1+1,l2,r2);
}
int main(){
scanf("%lld%lld",&n,&m);
for(ll i=1;i<=n;i++){
scanf("%lld",&aa);
s.insert(asd(i,i,aa));
}
s.insert(asd(n+1,n+1,0));
for(ll i=1;i<=m;i++){
scanf("%lld",&aa);
if(aa==1){
scanf("%lld%lld",&bb,&cc);
printf("%lld\n",qh(bb,cc));
} else if(aa==2){
scanf("%lld%lld%lld",&bb,&cc,&dd);
Assign(bb,cc,dd);
} else if(aa==3){
scanf("%lld%lld%lld",&bb,&cc,&dd);
ad(bb,cc,dd);
} else if(aa==4){
scanf("%lld%lld%lld%lld",&bb,&cc,&dd,&ee);
fz(bb,cc,dd,ee);
} else if(aa==5){
scanf("%lld%lld%lld%lld",&bb,&cc,&dd,&ee);
jh(bb,cc,dd,ee);
} else {
scanf("%lld%lld",&bb,&cc);
xz(bb,cc);
} }
it2=Split(n+1),it1=Split(1);
for(it=it1;it!=it2;it++){
for(ll i=it->l;i<=it->r;i++)printf("%lld ",it->val%mod);
}
printf("\n");
return 0;
}

洛谷 P5350 序列 珂朵莉树的更多相关文章

  1. 洛谷P2572 [SCOI2010]序列操作(珂朵莉树)

    传送门 珂朵莉树是个吼东西啊 这题线段树代码4k起步……珂朵莉树只要2k…… 虽然因为这题数据不随机所以珂朵莉树的复杂度实际上是错的…… 然而能过就行对不对…… (不过要是到时候noip我还真不敢打… ...

  2. 洛谷$P2572\ [SCOI2010]$ 序列操作 线段树/珂朵莉树

    正解:线段树/珂朵莉树 解题报告: 传送门$w$ 本来是想写线段树的,,,然后神仙$tt$跟我港可以用珂朵莉所以决定顺便学下珂朵莉趴$QwQ$ 还是先写线段树做法$QwQ$? 操作一二三四都很$eas ...

  3. 洛谷AT2342 Train Service Planning(思维,动态规划,珂朵莉树)

    洛谷题目传送门 神仙思维题还是要写点东西才好. 建立数学模型 这种很抽象的东西没有式子描述一下显然是下不了手的. 因为任何位置都以\(k\)为周期,所以我们只用关心一个周期,也就是以下数都在膜\(k\ ...

  4. 洛谷P4344 [SHOI2015]脑洞治疗仪(珂朵莉树)

    传送门 看到区间推倒……推平就想到珂朵莉树 挖脑洞直接assign,填坑先数一遍再assign再暴力填,数数的话暴力数 //minamoto #include<iostream> #inc ...

  5. 洛谷P2787 语文1(chin1)- 理理思维(珂朵莉树)

    传送门 一看到区间推倒……推平操作就想到珂朵莉树 区间推平直接assign,查询暴力,排序的话开一个桶统计,然后一个字母一个字母加就好了 开桶统计的时候忘了保存原来的左指针然后挂了233 //mina ...

  6. 洛谷P2082 区间覆盖(加强版)(珂朵莉树)

    传送门 虽然是黄题而且还是一波离散就能解决的东西 然而珂朵莉树还是很好用 相当于一开始区间全为0,然后每一次区间赋值,问最后总权值 珂朵莉树搞一搞就好了 //minamoto #include< ...

  7. [转]我的数据结构不可能这么可爱!——珂朵莉树(ODT)详解

    参考资料: Chtholly Tree (珂朵莉树) (应某毒瘤要求,删除链接,需要者自行去Bilibili搜索) 毒瘤数据结构之珂朵莉树 在全是珂学家的珂谷,你却不知道珂朵莉树?来跟诗乃一起学习珂朵 ...

  8. 『珂朵莉树 Old Driver Tree』

    珂朵莉树 珂朵莉树其实不是树,只是一个借助平衡树实现的数据结构,主要是对于有区间赋值的数据结构题,可以用很暴力的代码很高效地完成任务,当然这是建立在数据随机的基础上的. 即使数据不是随机的,写一个珂朵 ...

  9. 「学习笔记」珂朵莉树 ODT

    珂朵莉树,也叫ODT(Old Driver Tree 老司机树) 从前有一天,珂朵莉出现了... 然后有一天,珂朵莉树出现了... 看看图片的地址 Codeforces可还行) 没错,珂朵莉树来自Co ...

随机推荐

  1. 程序员必须掌握的Java 框架,小白学会之后15k不是问题

    Spring 的核心特性是什么?Spring 优点? Spring 的核心是控制反转(IoC)和面向切面(AOP) Spring 优点: 程序员必须掌握的Java 框架,学会之后50k不是问题 (1) ...

  2. FIS3安装与编译

    安装 FIS3 npm install -g fis3 -g 安装到全局目录,必须使用全局安装,当全局安装后才能在命令行(cmd或者终端)找到 fis3 命令 安装过程中遇到问题具体请参考 fis#5 ...

  3. Java中设置多个Access-Control-Allow-Origin跨域访问

    1.如果服务端是Java开发的,添加如下设置允许跨域即可,但是这样做是允许所有域名都可以访问,不够安全. response.setHeader("Access-Control-Allow-O ...

  4. 基于 Blazor 开发五子棋⚫⚪小游戏

    今天是农历五月初五,端午节.在此,祝大家端午安康! 端午节是中华民族古老的传统节日之一.端午也称端五,端阳.此外,端午节还有许多别称,如:午日节.重五节.五月节.浴兰节.女儿节.天中节.地腊.诗人节. ...

  5. 分享 HT 实用技巧:实现指南针和 3D 魔方导航

    前言 三维场景时常需要一个导航标识,用来确定场景所处的方位. 一般有两种表现形式:指南针.小方盒(方位魔方). 参考一下百度百科中的 maya 界面,可以看到右上角有一个标识方位的小盒子,说的就是它: ...

  6. 【python + NATAPP】实现内网穿透的简易数据传输

    1. 服务端 接收两张图像的地址,返回这两张图像的相似度 import os, shutil, requests import cv2 import numpy as np import imgs_s ...

  7. Mac下搭建react开发环境

    安装node 官网下载 https://nodejs.org/en/ 双击安装,接下来都是默认选择即可,直至安装成功 测试是否安装成功,分别输入以下命令: node -v npm -v 如下图所示,说 ...

  8. php抽奖功能

    在项目开发中经常会遇到花钱抽奖类型的需求.但是老板总是担心用户用小钱抽到大奖.这样会导致项目亏损.下边这段代码可以有效制止抽奖项目亏钱. 个人奖池: 语言:thinkphp redis mysql 表 ...

  9. Spring 获取单例流程(三)

    读完这篇文章你将会收获到 Spring 何时将 bean 加入到第三级缓存和第一级缓存中 Spring 何时回调各种 Aware 接口.BeanPostProcessor .InitializingB ...

  10. java中执行cmd命令

    一.java执行cmd命令的三种方式:http://www.jb51.net/article/80829.htm 参考:https://www.cnblogs.com/zhufu9426/p/7928 ...