洛谷 P5350 序列 珂朵莉树
题目描述

分析
操作一、二、三为珂朵莉树的基本操作,操作四、五、六稍作转化即可
不会珂朵莉树请移步至这里
求和操作
把每一段区间分别取出,暴力相加
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 序列 珂朵莉树的更多相关文章
- 洛谷P2572 [SCOI2010]序列操作(珂朵莉树)
传送门 珂朵莉树是个吼东西啊 这题线段树代码4k起步……珂朵莉树只要2k…… 虽然因为这题数据不随机所以珂朵莉树的复杂度实际上是错的…… 然而能过就行对不对…… (不过要是到时候noip我还真不敢打… ...
- 洛谷$P2572\ [SCOI2010]$ 序列操作 线段树/珂朵莉树
正解:线段树/珂朵莉树 解题报告: 传送门$w$ 本来是想写线段树的,,,然后神仙$tt$跟我港可以用珂朵莉所以决定顺便学下珂朵莉趴$QwQ$ 还是先写线段树做法$QwQ$? 操作一二三四都很$eas ...
- 洛谷AT2342 Train Service Planning(思维,动态规划,珂朵莉树)
洛谷题目传送门 神仙思维题还是要写点东西才好. 建立数学模型 这种很抽象的东西没有式子描述一下显然是下不了手的. 因为任何位置都以\(k\)为周期,所以我们只用关心一个周期,也就是以下数都在膜\(k\ ...
- 洛谷P4344 [SHOI2015]脑洞治疗仪(珂朵莉树)
传送门 看到区间推倒……推平就想到珂朵莉树 挖脑洞直接assign,填坑先数一遍再assign再暴力填,数数的话暴力数 //minamoto #include<iostream> #inc ...
- 洛谷P2787 语文1(chin1)- 理理思维(珂朵莉树)
传送门 一看到区间推倒……推平操作就想到珂朵莉树 区间推平直接assign,查询暴力,排序的话开一个桶统计,然后一个字母一个字母加就好了 开桶统计的时候忘了保存原来的左指针然后挂了233 //mina ...
- 洛谷P2082 区间覆盖(加强版)(珂朵莉树)
传送门 虽然是黄题而且还是一波离散就能解决的东西 然而珂朵莉树还是很好用 相当于一开始区间全为0,然后每一次区间赋值,问最后总权值 珂朵莉树搞一搞就好了 //minamoto #include< ...
- [转]我的数据结构不可能这么可爱!——珂朵莉树(ODT)详解
参考资料: Chtholly Tree (珂朵莉树) (应某毒瘤要求,删除链接,需要者自行去Bilibili搜索) 毒瘤数据结构之珂朵莉树 在全是珂学家的珂谷,你却不知道珂朵莉树?来跟诗乃一起学习珂朵 ...
- 『珂朵莉树 Old Driver Tree』
珂朵莉树 珂朵莉树其实不是树,只是一个借助平衡树实现的数据结构,主要是对于有区间赋值的数据结构题,可以用很暴力的代码很高效地完成任务,当然这是建立在数据随机的基础上的. 即使数据不是随机的,写一个珂朵 ...
- 「学习笔记」珂朵莉树 ODT
珂朵莉树,也叫ODT(Old Driver Tree 老司机树) 从前有一天,珂朵莉出现了... 然后有一天,珂朵莉树出现了... 看看图片的地址 Codeforces可还行) 没错,珂朵莉树来自Co ...
随机推荐
- Machine Learning Note
[Andrew Ng NIPS2016演讲]<Nuts and Bolts of Applying Deep Learning (Andrew Ng) 中文详解:https://mp.weixi ...
- oracle 索引失效原因_汇总
1) 没有查询条件,或者查询条件没有建立索引 2) 在查询条件上没有使用引导列 3) 查询的数量是大表的大部分,应该是30%以上. 4) 索引本身失效 5) 查询条件使用函数在索引列上,或者对索引列进 ...
- web安全中的session攻击
运行着个简单的demo后,打开login.jsp,使用firebug或chrome会发现,即使没有登录,我们也会有一个JSESSIONID,这是由服务器端在会话开始是通过set-cookie来设置的匿 ...
- 微信小程序之页面跳转(tabbar跳转及页面内跳转)
一.简介 微信小程序页面主要分为tabbar页面和应用内页面,这两种页面的跳转方式不同 二.tabBar页面跳转 tabBar 是底部导航栏页面,如下图 在app.json中的配置如下: 跳转方式如下 ...
- PHP输入流
PHP输入流php://input,对于这个的官方解释是: php://input可以读取没有处理过的POST数据.相较于$HTTP_RAW_POST_DATA而言,它给内存带来的压力较小,并且不需要 ...
- volatile与lock前缀指令
前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是java.util.concurrent包的核心,没有volatile就没有这么多的并发类给我们使用. 本文详细解读一下v ...
- express高效入门教程(2)
2.请求和响应 2.1.请求相关 2.1.1.返回一个html页面 // 注意path模块需要先引入 app.get('/', function (req, res){ res.sendFile(pa ...
- postman不能启动的问题解决
1.postman启动不了,启动时提示“postman resolving transporter buffer”,不能正常启动 第一步,删除:在chrome-更多工具-扩展程序里面删除了postma ...
- Spring 获取单例流程(一)
读完这篇文章你将会收获到 在 getBean 方法中, Spring 处理别名以及 factoryBean 的 name Spring 如何从多级缓存中根据 beanName 获取 bean Spri ...
- django项目常见报错集
1.mysqlclient 目前不支持高版本python3 django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or new ...