点此看题面

大致题意: 告诉你\(n\)只蜡笔的颜色,有两种操作:第一种操作将第\(x\)只蜡笔颜色改成\(y\),第二种操作询问区间\([l,r]\)内有多少种颜色的蜡笔。

考虑普通莫队

这题目第一眼看上去感觉和【洛谷2709】小B的询问很像,然后就自然而然地会想到用莫队去做。

但是,在仔细想想,就会发现这道题中有修改,普通的莫队是做不了这样的题目的。

于是,我们就要用一种新的算法:带修莫队

带修莫队

如果你会带修莫队,那么这题应该就是一道简单的板子题了。

对于每一个询问,记录下在这次询问前进行了几次修改

而对于每一个修改,记录下当前修改元素修改前的值

这样,就可以对于每一个询问,将没有执行的修改执行掉,将多执行的修改撤销掉即可。

代码

#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define LL long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define tc() (A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++)
#define pc(ch) (pp_<100000?pp[pp_++]=(ch):(fwrite(pp,1,100000,stdout),pp[(pp_=0)++]=(ch)))
#define N 50000
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
int pp_=0;char ff[100000],*A=ff,*B=ff,pp[100000];
using namespace std;
int n,m,blo,q_num,o_num,col[N+5],lst[N+5],pos[N+5],res[N+5],cnt[1000005];
struct Query//记录询问
{
int l,r,pos,k;//l和r记录询问区间,pos记录这个询问的编号,方便最后答案的输出,k记录这个询问前执行的操作数
}q[N+5];
struct Operation//记录操作
{
int x,y,z;//x记录修改的元素的编号,y记录要修改成的值,z记录修改前的值,方便撤销
}o[N+5];
inline void read(int &x)
{
x=0;static char ch;
while(!isdigit(ch=tc()));
while(x=(x<<3)+(x<<1)+ch-48,isdigit(ch=tc()));
}
inline void read_alpha(char &x)
{
while(!isalpha(x=tc()));
}
inline void write(int x)
{
if(x>9) write(x/10);
pc(x%10+'0');
}
inline bool cmp(Query x,Query y)//排序
{
if(pos[x.l]^pos[y.l]) return pos[x.l]<pos[y.l];//如果两个询问的l不在同一块内
if(pos[x.r]^pos[y.r]) return pos[x.r]<pos[y.r];//如果两个询问的r不在同一块内
return x.k<y.k;//比较两个询问执行操作的个数
}
int main()
{
register int i,j,x,y;register char ch;
for(read(n),read(m),blo=pow(n,2.0/3),i=1;i<=n;++i) read(col[i]),lst[i]=col[i],pos[i]=(i-1)/blo+1;
for(i=1;i<=m;++i)
{
read_alpha(ch),read(x),read(y);
if(ch^'R') q[++q_num].l=x,q[q_num].r=y,q[q[q_num].pos=q_num].k=o_num;
else o[++o_num].x=x,o[o_num].y=y,o[o_num].z=lst[x],lst[x]=y;
}
register int L=0,R=0,K=0,ans=0;//L和R记录当前答案的区间,K记录当前执行的操作数,ans记录当前的答案,初始化全为0
for(sort(q+1,q+q_num+1,cmp),i=1;i<=q_num;++i)
{
while(K<q[i].k)//如果当前执行的操作数少于当前询问执行的操作数
{
++K;
if(L<=o[K].x&&o[K].x<=R)//如果修改的点在L到R区间内
{
if(!--cnt[col[o[K].x]]) --ans;//如果删除了原先的颜色使得这种颜色的个数为0,那么将ans减1
if(!cnt[o[K].y]++) ++ans;//如果加上了新的颜色使得颜色个数增加了1,那么将ans加1
}
col[o[K].x]=o[K].y;//修改颜色
}
while(K>q[i].k)//如果当前执行掉操作数多余当前询问执行的操作数
{
if(L<=o[K].x&&o[K].x<=R)//如果修改的点在L到R区间内
{
if(!--cnt[col[o[K].x]]) --ans;//如上
if(!cnt[o[K].z]++) ++ans;//如上
}
col[o[K].x]=o[K].z,--K;//如上
}
while(R<q[i].r) if(!cnt[col[++R]]++) ++ans;//如果当前的R小于当前询问的r,那么将R向右移
while(L>q[i].l) if(!cnt[col[--L]]++) ++ans;//如果当前的L大于当前询问的l,那么将L向左移
while(R>q[i].r) if(!--cnt[col[R--]]) --ans;//如果当前的R大于当前询问的r,那么将R向左移
while(L<q[i].l) if(!--cnt[col[L++]]) --ans;//如果当前的L小于当前询问的l,那么将L向右移
res[q[i].pos]=ans;//记录答案
}
for(i=1;i<=q_num;++i) write(res[i]),pc('\n');
return fwrite(pp,1,pp_,stdout),0;
}

【BZOJ2120】数颜色(带修莫队)的更多相关文章

  1. bzoj2120 数颜色——带修莫队

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2120 带修改的莫队: 用结构体存下修改和询问,排好序保证时间后就全局移动修改即可: 参考了T ...

  2. bzoj2120: 数颜色 带修莫队

    墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P ...

  3. BZOJ 2120 数颜色 (带修莫队)

    2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 6367  Solved: 2537[Submit][Status][Discuss] ...

  4. bzoj 2120 数颜色 (带修莫队)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2120 题意:两种操作:Q 询问区间  l - r  内颜色的种类 ,R 单点修改 思路 ...

  5. BZOJ2120数颜色(带修改莫队)

    莫队算法是一种数据结构的根号复杂度替代品,主要应用在询问[l,r]到询问[l+1,r]和[l,r+1]这两个插入和删除操作复杂度都较低的情况下.具体思想是:如果把一个询问[l,r]看做平面上的点(l, ...

  6. 【bzoj2120】数颜色 带修莫队

    数颜色 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画 ...

  7. [国家集训队][bzoj2120] 数颜色 [带修改莫队]

    题面: 传送门 思路: 这道题和SDOI2009的HH的项链很像,只是多了一个修改 模板套上去呀 莫队学习请戳这里:莫队 Code: #include<iostream> #include ...

  8. BZOJ2120/洛谷P1903 [国家集训队] 数颜色 [带修改莫队]

    BZOJ传送门:洛谷传送门 数颜色 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R ...

  9. NOI模拟 颜色 - 带修莫队/树套树

    题意: 一个颜色序列,\(a_1, a_2, ...a_i\)表示第i个的颜色,给出每种颜色的美丽度\(w_i\),定义一段颜色的美丽值为该段颜色的美丽值之和(重复的只计算一次),每次都会修改某个位置 ...

  10. bzoj 2120 数颜色 带修改莫队

    带修改莫队,每次查询前调整修改 #include<cstdio> #include<iostream> #include<cstring> #include< ...

随机推荐

  1. loj#6517. 「雅礼集训 2018 Day11」字符串(回滚莫队)

    传送门 模拟赛的时候纯暴力竟然骗了\(70\)分-- 首先对于一堆\(g\)怎么计算概率应该很好想,用总的区间数减去不合法的区间数就行了,简而言之对\(g\)排个序,每一段长为\(d\)的连续序列的区 ...

  2. 让你的spring-boot应用日志随心所欲--spring boot日志深入分析

    1.spring boot日志概述 spring boot使用Commons Logging作为内部的日志系统,并且给Java Util Logging,Log4J2以及Logback都提供了默认的配 ...

  3. 关于苹果出现NaN的情况----由Date格式解析方式不同引起的Bug

    源于一个工作中遇到的问题:IOS 上时间显示为 NaN,而安卓上时间显示正常. 问题的根源在于 安卓 和 苹果 对于 JS Date 对象的不同解析. 安卓: new Date("2018- ...

  4. python之Selenium库的使用

    一  什么是Selenium selenium 是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(Selenium Remote Control)和测试的并 ...

  5. 【ACM】拦截导弹 - 0-1背包问题

    拦截导弹 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到 ...

  6. java——集合、泛型、ArrayList、LinkedList、foreach循环、模拟ktv点歌系统

    集合:一系列特殊的类,这些类可以存储任意类型的对象,长度可变,集合类都在java.util包中. 但是集合记不住对象的类型,当把对象从集合中取出时这个对象的编译类型就变成了Object类型.这样在取元 ...

  7. 关于Function.prototype.apply.call的一些补充

    宿主对象,在javascript中有三类对象,本地对象,内置对象和宿主对象.其他两类暂且不提,宿主对象是指什么呢(DOM BOM),控制台对象是文档对象模型的扩展,也被认为是宿主对象.那么,它们有什么 ...

  8. Storm概念学习系列之Stream消息流 和 Stream Grouping 消息流组

    不多说,直接上干货! Stream消息流是Storm中最关键的抽象,是一个没有边界的Tuple序列. Stream Grouping 消息流组是用来定义一个流如何分配到Tuple到Bolt. Stre ...

  9. Spring Junit测试(非web,即不包含Controller测试)

    使用Spring-Test对Spring框架进行单元测试 配置过程: lib加入导入spring-test.jar和junit包 或者使用Maven依赖: <dependency> < ...

  10. 设计模式--观察者模式(KVO)

    观察者模式(Observer):观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 举个例子, ...