题目大意:

给定一个序列,有2个操作:

1. 区间覆盖。
2. 区间数颜色。

解题思路:

珂朵莉树+树套树。

看到区间覆盖当然想到珂朵莉树然而这是Ynoi

所以我们得优化掉珂朵莉树那个暴力过程。

考虑对每个位置,记录它这个颜色前一次出现的位置pre(它本身是第一次则为0)。

对一段颜色相同的区间,除了第一个位置,其他位置的pre都是位置-1。

用树套树,第一维为原本位置,第二维为pre,然后对于查询$[l,r]$区间的颜色个数,相当于$[l,r]$区间,pre在$[0,l-1]$的个数。

考虑一次修改,最多增加$O(m)$个区间,所以总区间个数是$O(n+m)$的。所以暴力删除复杂度是对的。

用珂朵莉树(其实是个set,不过珂朵莉树的split比较方便)维护相同颜色区间,对每种颜色再开set存所有区间。

然后对于每次修改,先把pre可能变动的位置弄出来,再修改珂朵莉树和set里的信息,最后再重新求那些pre,在树套树上修改即可。

时间复杂度$O((n+m)\log^2 n)$。

C++ Code:

#include<cstdio>
#include<cctype>
#include<set>
#include<map>
const int N=100005,M=1.5e7+5;
struct istream{
char buf[23333333],*s;
inline istream(){
buf[fread(s=buf,1,23333330,stdin)]='\n';fclose(stdin);
}
inline istream&operator>>(int&d){
for(d=0;!isdigit(*s);++s);
while(isdigit(*s))d=(d<<3)+(d<<1)+(*s++^'0');
return*this;
}
}cin;
struct ostream{
char buf[12000005],*s;
inline ostream(){s=buf;}
inline ostream&operator<<(int d){
if(!d)*s++='0';else{
static int w;
for(w=1;w<=d;w*=10);for(;w/=10;d%=w)*s++=d/w^'0';
}
return*this;
}
inline ostream&operator<<(const char&c){*s++=c;return*this;}
inline void flush(){fwrite(buf,1,s-buf,stdout);s=buf;}
inline~ostream(){flush();}
}cout;
struct node{
int l,r;mutable int col;
inline bool operator<(const node&r)const{return l<r.l;}
};
std::set<node>s;
typedef std::set<node>::iterator iter;
std::set<std::pair<int,int> >cl[N<<1];
std::map<int,int>ys;int tot=0,nodes=0;
int n,m,pp[N],rt[N],pw[N];
int ls[M],rs[M],sz[M];
iter split(int pos){
iter it=s.lower_bound((node){pos});
if(it!=s.end()&&it->l==pos)return it;
--it;
const int l=it->l,r=it->r,val=it->col;
s.erase(it);
cl[val].erase(std::make_pair(l,r));
s.insert((node){l,pos-1,val});
cl[val].insert(std::make_pair(l,pos-1));
cl[val].insert(std::make_pair(pos,r));
return s.insert((node){pos,r,val}).first;
}
void modify2D(int&o,int l,int r,const int&pos,const int&dlt){
if(!o)o=++nodes;
sz[o]+=dlt;
if(l==r)return;
const int mid=l+r>>1;
if(pos<=mid)modify2D(ls[o],l,mid,pos,dlt);else modify2D(rs[o],mid+1,r,pos,dlt);
}
void modify1D(int i,int pre,int f){for(;i<=n;i+=i&-i)modify2D(rt[i],0,n,pre,f);}
int query2D(int o,int l,int r,const int&L,const int&R){
if(!o)return 0;
if(L<=l&&r<=R)return sz[o];
const int mid=l+r>>1;
if(L<=mid&&mid<R)return query2D(ls[o],l,mid,L,R)+query2D(rs[o],mid+1,r,L,R);
if(L<=mid)return query2D(ls[o],l,mid,L,R);return query2D(rs[o],mid+1,r,L,R);
}
int query1D(int l,int r){
int ret=0;
for(int i=r;i;i^=i&-i)ret+=query2D(rt[i],0,n,0,l-1);
for(int i=l-1;i;i^=i&-i)ret-=query2D(rt[i],0,n,0,l-1);
return ret;
}
int main(){
cin>>n>>m;
int preL=1,pre;cin>>pre;
for(int i=2;i<=n;++i){
int now;
cin>>now;
if(now!=pre)s.insert((node){preL,i-1,pre}),preL=i,pre=now;
}
s.insert((node){preL,n,pre});
s.insert((node){n+1});
for(int i=1;i<=n+m;++i)cl[i].insert(std::make_pair(0,0));
for(iter i=s.begin();i!=s.end();++i){
if(i->l>n)break;
if(!ys.count(i->col))ys[i->col]=++tot;
i->col=ys[i->col];
cl[i->col].insert(std::make_pair(i->l,i->r));
for(int j=i->l+1;j<=i->r;++j)modify1D(j,j-1,1),pw[j]=j-1;
modify1D(i->l,pp[i->col],1);pw[i->l]=pp[i->col];
pp[i->col]=i->r;
}
while(m--){
int op,l,r;
cin>>op>>l>>r;
if(op==1){
static std::set<int>trans;
trans.clear();
int x;cin>>x;if(!ys.count(x))ys[x]=++tot;x=ys[x];
iter R=split(r+1),L=split(l);
for(iter i=L;i!=R;++i){
trans.insert(i->l);
auto it=cl[i->col].upper_bound(std::make_pair(i->l,i->r));
if(it!=cl[i->col].end())trans.insert(it->first);
cl[i->col].erase(std::make_pair(i->l,i->r));
}
s.erase(L,R);
s.insert((node){l,r,x});
cl[x].insert(std::make_pair(l,r));
const auto it=(cl[x].upper_bound(std::make_pair(l,r)));
if(it!=cl[x].end())trans.insert(it->first);
for(int it:trans){
iter info=--s.upper_bound((node){it});
modify1D(it,pw[it],-1);
if(it==info->l)pw[it]=(--cl[info->col].lower_bound(std::make_pair(info->l,info->r)))->second;else
pw[it]=it-1;
modify1D(it,pw[it],1);
}
}else cout<<query1D(l,r)<<'\n';
}
return 0;
}

[Ynoi2016]镜中的昆虫的更多相关文章

  1. bzoj4941: [Ynoi2016]镜子里的昆虫

    维护每个位置x的上一个相等的位置pv[x],可以把询问表示成l<=x<=r,pv[x]<l的形式,对一次修改,均摊改变O(1)个pv的取值,因此可以用平衡树预处理出pv的变化,用cd ...

  2. 2021record

    2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...

  3. Codeforces 453E - Little Pony and Lord Tirek(二维线段树+ODT)

    Codeforces 题目传送门 & 洛谷题目传送门 一道难度 *3100 的 DS,而且被我自己搞出来了! 不过我终究还是技不如人,因为这是一个 \(n\log^2n\) + 大常数的辣鸡做 ...

  4. ZJOI2019Round#1

    考的这么差二试基本不用去了 不想说什么了.就把这几天听课乱记的东西丢上来吧 这里是二试乱听课笔记ZJOI2019Round#2 ZJOI Round#1 Day1 M.<具体数学>选讲 罗 ...

  5. 2.lvm动态逻辑卷

    Lvm动态逻辑卷 一.             基本概念 LVM 把实际的物理磁盘数据映射到一个简单而灵活的虚拟逻辑存储视图上,藉以控制磁盘资源: 也就是重新考虑了管理文件系统和卷的方法,在文件系统管 ...

  6. VR定制开发、AR定制开发(长年承接虚拟现实、增强现实应用、VR游戏定制开发,北京公司,可签合同)

    Cardboard SDK for Unity的使用 上一篇文章作为系列的开篇,主要是讲了一些虚拟现实的技术和原理,本篇就会带领大家去看一看谷歌的Cardboard SDK for Unity,虽然目 ...

  7. 承接Unity3D外包公司 — 技术分享

    Cardboard SDK for Unity的使用 上一篇文章作为系列的开篇,主要是讲了一些虚拟现实的技术和原理,本篇就会带领大家去看一看谷歌的Cardboard SDK for Unity,虽然目 ...

  8. 阿里前CEO卫哲用自己10余年经历,倾诉B2B的三差、四率、两大坑

    今日(12 月 28 日),嘉御基金创始人.阿里巴巴(B2B)前 CEO 卫哲在第三届中国 B2B 电子商务大会上进行了"B2B 冬天里的春天"的主题分享.他提出中国 B2B 行业 ...

  9. 合金装备V 幻痛 制作技术特辑

    合金装备V:幻痛 制作特辑 资料原文出自日版CGWORLD2015年10月号   在[合金装备4(Metal Gear Solid IV)]7年后,序章作品[合金装备5 :原爆点 (Metal Gea ...

随机推荐

  1. [iOS]怎样在iOS开发中切换显示语言实现国际化

    1.在Project设置,加入中英两种语言: 2.新建Localizable.strings文件,作为多语言相应的词典,存储多种语言,点击右側Localization,勾选中英: watermark/ ...

  2. NJUPT JAVA语言 流处理程序设计

    一. 实验目的和要求 实验目的和要求:要求学生能在学习和理解课堂学习内容中JAVA流编程理论的基础上,学习并逐步掌握JAVA流程序的编写和调试,学习依据处理需求对不同流的正确选择使用和组合用法. 实验 ...

  3. 前端页面a标签嵌套a标签效果的两种解决方案

    这是由工作中的一个小改动需求得到的这个解决方案的:那个需求是这样的,如图: 需求原来是球队名字没有点击功能的,而蓝色方框两队之间的比赛点击的时候会跳转到比赛文字直播页面.现在需要要求点击球队名字要跳转 ...

  4. BNU 13259.Story of Tomisu Ghost 分解质因子

    Story of Tomisu Ghost It is now 2150 AD and problem-setters are having a horrified time as the ghost ...

  5. bzoj 1026 [ SCOI2009 ] windy数 —— 数位DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1026 蛮简单的数位DP,预处理 f[i][j] 表示 i 位数,以 j 开头的 windy ...

  6. rpmbuild

    rpm2cpio xxx.rpm | cpio -div

  7. python 实现线程之间的通信

    前言:因为GIL的限制,python的线程是无法真正意义上并行的.相对于异步编程,其性能可以说不是一个等量级的.为什么我们还要学习多线程编程呢,虽然说异步编程好处多,但编程也较为复杂,逻辑不容易理解, ...

  8. C#利用ICSharpCode将远程文件打包并下载

    应用于ASP.NET MVC中 方法主体代码: public void GetFilesByOrder(string Order_ID, string IntNumber) { MemoryStrea ...

  9. C#:使用FastReport打印带图片传参模板的实现方法

    大家都知道,C#打印图片可以直接调用PrintDocument控件的PrintPage事件,通过画刷对image对象直接进行绘制.但是这种方法存在局限,例如如果打印的图片需要按纸张大小进行缩放的话,那 ...

  10. android悬浮球实现各种功能、快速开发框架、单词、笔记本、应用市场应用等源码

    Android精选源码 悬浮球,实现一键静音,一键锁频,一键截屏等功能 一个Android快速开发框架,MVP架构 Android QQ小红点的实现源码 android一款单词应用完整app源码 an ...