题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2120

2120: 数颜色

Time Limit: 6 Sec  Memory Limit: 259 MB
Submit: 10514  Solved: 4398
[Submit][Status][Discuss]

Description

墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?

Input

第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。

Output

对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。

Sample Input

6 5
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6

Sample Output

4
4
3
4

HINT

对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。

2016.3.2新加数据两组by Nano_Ape

·述大意:

       多个区间询问,询问[l,r]中颜色的种类数。可以单点修改颜色。

·分析:

莫队可以修改?那不是爆炸了吗。

这类爆炸的问题被称为带修莫队(可持久化莫队)。

按照美妙类比思想,可以引入一个“修改时间”,表示当前询问是发生在前Time个修改操作后的。也就是说,在进行莫队算法时,看看当前的询问和时间指针(第三个指针,别忘了l,r)是否相符,然后进行时光倒流或者时光推移操作来保证答案正确性。

·Sort的构造。仅靠原来的sort关键字会使得枚举每个询问都可能因为时间指针移动的缘故要移动n次,总共就n2次,那还不如写暴力。

·为了防止这样的事情发生,再加入第三关键字Tim:

·如何理解时间复杂度?

首先,R和Tim的关系就像L和R的关系一样:只有在前者处于同块时,后者才会得到排序的恩赐,否则sort会去满足前者,使得后者开始乱跳。

依旧像上文那样:枚举m个答案,就一个m了。设分块大小为unit。

分类讨论:

①对于l指针,依旧是O(unit*n)

②对于r指针,依旧是O(n*n/unit)

③对于T指针(即Time):

    类比r时间复杂度的计算。我们要寻找有多少个单调段(一个单调段下来最多移动n次)。上文提到,当且仅当两个询问l在同块,r也在同块时,才会对可怜的Tim进行排序。局势明朗。对于每一个l的块,里面r最坏情况下占据了所有的块,所以最坏情况下:有n/unit个l的块,每个l的块中会有n/unit个r的块,此时,在一个r块里,就会出现有序的Tim。所以Tim的单调段个数为:(n/unit)*(n/unit)。每个单调段最多移动n次。

所以:O((n/unit)2*n)

三个指针汇总:O(unit*n+n2/unit+(n/unit)2*n)

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=1000000+50;
int block;
int a[maxn],b[maxn],ans1[maxn];
int ans=0;
struct Q
{int x,y,num,tim;
}q[maxn];
struct U
{int x,y;
}tw[maxn];
bool cmp(const Q a,const Q b)
{if(a.x/block==b.x/block){if(a.y/block==b.y/block) return a.tim<b.tim;return a.y/block<b.y/block;}return a.x/block<b.x/block;
}
void solve(int n,int add)
{b[a[n]]+=add;if(b[a[n]]==1&&add==1) ans++;else if(b[a[n]]==0&&add==-1) ans--;
}
void time_charge(int n,int t)
{if(q[n].x<=tw[t].x&&tw[t].x<=q[n].y){b[a[tw[t].x]]--;if(b[a[tw[t].x]]==0) ans--;b[tw[t].y]++;if(b[tw[t].y]==1) ans++;}swap(tw[t].y,a[tw[t].x]);
}
int main()
{int N,M,t=0,p1=0,p2=0;char c[10];scanf("%d%d",&N,&M);block=pow(N,0.66666);for(int i=1;i<=N;i++) scanf("%d",&a[i]);for(int i=0;i<M;i++){scanf("%s",c);if(c[0]=='Q'){scanf("%d%d",&q[p1].x,&q[p1].y);q[p1].num=p1;q[p1].tim=t;p1++;}else{t++;scanf("%d%d",&tw[t].x,&tw[t].y);}}sort(q,q+p1,cmp);int L=1,R=0,T=0;for(int i=0;i<p1;i++){while(R<q[i].y)//往右走
        {solve(R+1,1);R++;}while(R>q[i].y){solve(R,-1);R--;}while(L<q[i].x){solve(L,-1);L++;}while(L>q[i].x){solve(L-1,1);L--;}while(T<q[i].tim){time_charge(i,T+1);T++;}while(T>q[i].tim){time_charge(i,T);T--;}ans1[q[i].num]=ans;}for(int i=0;i<p1;i++) printf("%d\n",ans1[i]);return 0;
}

转载于:https://www.cnblogs.com/caijiaming/p/10846914.html

2120: 数颜色(带修莫队)相关推荐

  1. P1903 数颜色 (带修莫队)

    题目传送门 ~~~ 题目大意 给一个有 n 个元素的数组 a,有 m 次操作,操作如下: Q 操作,询问区间 (l, r) 不同元素的个数 R 操作,把第 x 个元素修改为 y 对于每次 Q 操作,输 ...

  2. [国家集训队]数颜色 / 维护队列 (带修莫队模板题)

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

  3. 【BZOJ2120】数颜色,带修莫队

    Time:2016.09.08 Author:xiaoyimi 转载注明出处谢谢 思路: 第一次写带修莫队 感觉还是挺简单的 每一次的修改都是一个时间的变动,即修改一次,时间+1(s) 没有修改的查询 ...

  4. 莫队+带修莫队模板与总结

    以下总结参考了许多大佬们的博客,开篇先(大佬)% 莫队的入门题目主要为莫队和带修莫队在,这里就先在这里总结一下这两类题目的一些属性. 我认为莫队本质是一种比较优化的暴力查找法.在通过分块操作后把复杂度 ...

  5. 莫队算法 (普通莫队、带修莫队、树上莫队)

    莫队算法 主要基于分块的思想 用结构体记录询问的左右端点及询问编号 (这是一个离线算法) 通过排序优化指针扫描顺序优化时间复杂度 . 1.普通莫队 例题:SP3267 DQUERY - D-query ...

  6. 莫队算法(普通莫队、带修莫队、树上莫队、不删除莫队)学习笔记【理解+套路/核心代码+例题及题解】

    一.理解 我的理解就是巧妙的暴力,利用双指针以及分块思想,巧妙的移动双指针,时间复杂度可以达到O(NlogN). 强推博客:写的又好又全.链接 二.套路 1.普通莫队 [1]核心代码 bool cmp ...

  7. 莫队算法学习笔记(二)——带修莫队

    前言:什么是莫队 莫队算法,是一个十分优雅的暴力. 普通的莫队可以轻松解决一些离线问题,但是,当遇上了一些有修改操作的问题,普通莫队就无能为力了. 于是,改进后的莫队--带修莫队就这样产生了. L i ...

  8. HDU - 6610 Game(带修莫队)

    题目链接:点击查看 题目大意:给出一个长度为 n 的序列 a,sum 为数列 a 的前缀异或和,再给出 m 次操作,每次操作分为两种类型: 1 l r:询问 sum 在区间 [ l , r ] 内有多 ...

  9. 分治 —— 莫队算法 —— 带修莫队

    [概述] 普通莫队由于强制离线是不能修改的,但对于强制在线的题,可以在普通莫队的基础上强行加上一维时间轴 time,表示这次操作的时间,即在每个询问前已经完成了多少次修改. 简单来说,就是将询问 [l ...

最新文章

  1. Linux 下 LaTeX 2018 安装与使用
  2. PHP微信SDK——Zebra-Wechat
  3. Android 应用程序发布流程注意事项(整理)
  4. Django(part35)--多对多映射
  5. 行列式、LGV、矩阵树学习笔记
  6. 【RTOS】基于V7开发板的uCOS-III,uCOS-II,RTX4,RTX5,FreeRTOS原版和带CMSIS-RTOS V2封装层版全部集齐...
  7. ubuntu - 如何以root身份使用图形界面管理文件?
  8. HDFS的Block size的默认大小
  9. Qt学习笔记-国际化
  10. 批处理的高吞吐率和高延迟的解释
  11. 微信支付JSAPI掉不起来支付按钮是什么原因?(原创)
  12. bat执行cmd命令_kettle定时任务pan.bat和kitchen.bat
  13. 自助友情链接交换网站php源码,友情链接交换系统
  14. 对抗机器学习—— 迭代FGSM
  15. 2.1MAC协议概述
  16. win7 计算机 地址栏扫描,Win7系统添加地址栏的两种方法
  17. java脚本错误修复,win10系统使用iE浏览器时不断出现Java活动脚本功能出错问题的操作技巧...
  18. Mac OS X 10.13.6升级到更高版本的方法
  19. 梯度下降及python实现
  20. 画一个单实线,方向可以定制

热门文章

  1. vss登录invalid handle问题的解决办法
  2. 阿里、腾讯 | 算法岗面试复盘
  3. 假如BERT系论文变成Commit History
  4. 中props使用this报错_为什么在静态方法中不能使用this
  5. 独立站需要用到哪些营销手段?
  6. java中的几个“区别”总结
  7. 读书笔记——《程序员的思维修炼:开发认知潜能的九堂课》
  8. 微信小程序遇到的程序异步执行导致数据库读写异常的问题
  9. 季节性的分析才不简单,小心不要在随机数据中也分析出季节性...
  10. element 方法返回的boolean被当成字符串了_quot;==quot;和 equals 方法有什么区别