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。

正解:分块

解题报告:

  看到这道题我的第一感觉是,咦,暴力可做?!我这种蒟蒻果然第一个想的是暴力。

  考虑分块,维护一个pre数组,我们可以把询问视为对于一个区间[l,r]查询有多少个元素的pre小于l。是不是觉得分块很可做??

  但是我发现我的分块比较萎,和暴力差不多,后来发现其实是因为修改的时候每次发现改变了颜色之后我要全部重构一遍,然而我并不知道怎么改,就这样吧。。。

 //It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#ifdef WIN32
#define OT "%I64d"
#else
#define OT "%lld"
#endif
using namespace std;
typedef long long LL;
const int MAXN = ;
const int MAXC = ;
int n,m,size,tot,ans;
int a[MAXN],belong[MAXN],last[MAXC];
int pre[MAXN],pre_sort[MAXN];
char ch[];
//相当于是查询区间里有多少个元素pre<l inline int getint()
{
int w=,q=;
char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar();
if (c=='-') q=, c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar();
return q ? -w : w;
} inline void rebuild(int x){
int l=(x-)*size+,r=x*size;
for(int i=l;i<=r;i++) pre_sort[i]=pre[i];
sort(pre_sort+l,pre_sort+r+);
} inline void Init(){
int block=sqrt(n); if(n%block) size=block+; else tot=size=block;
if(n%size) tot=n/size+; else tot=n/size;
for(int i=;i<=n;i++) {
a[i]=getint(); belong[i]=(i-)/size+;
pre[i]=last[a[i]]; last[a[i]]=i;
}
for(int i=;i<=tot;i++) rebuild(i);
} inline int search(int x,int val) {
int l=(x-)*size+,r=x*size,mid; int cun=l;
int pos=l-;//注意一下如果不能更新应该返回0
while(l<=r) {
mid=(l+r)>>;
if(pre_sort[mid]<val) pos=mid,l=mid+;
else r=mid-;
}
return pos-cun+;
} inline void ask(){
int x,y; x=getint(); y=getint();
ans=;
if(belong[x]==belong[y]) {
for(int i=x;i<=y;i++) if(pre[i]<x) ans++;
printf("%d\n",ans); return ;
}
for(int i=x;i<=belong[x]*size;i++) if(pre[i]<x) ans++;
for(int i=(belong[y]-)*size+;i<=y;i++) if(pre[i]<x) ans++;
for(int i=belong[x]+;i<belong[y];i++) ans+=search(i,x);
printf("%d\n",ans);
} inline void update(){
for(int i=;i<=n;i++) last[a[i]]=;
int x,y; x=getint(); y=getint();
a[x]=y;
for(int i=;i<=n;i++) {
if(pre[i]!=last[a[i]]) {
pre[i]=last[a[i]];
rebuild(belong[i]);
}
last[a[i]]=i;
}
} inline void work(){
n=getint(); m=getint();
Init();
while(m--) {
scanf("%s",ch);
if(ch[]=='Q') ask();
else update();
}
} int main()
{
work();
return ;
}

BZOJ2120 数颜色的更多相关文章

  1. BZOJ2120 数颜色 【带修莫队】

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

  2. bzoj2120 数颜色 莫队 带修改

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

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

    2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MB Submit: 6579  Solved: 2625 [Submit][Status][Discus ...

  4. BZOJ2120 数颜色 —— 待修改莫队

    题目链接:https://vjudge.net/problem/HYSBZ-2120 2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit:  ...

  5. BZOJ2120 数颜色(树套树)

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

  6. [Bzoj2120]数颜色 (非正解 )(莫队)

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

  7. BZOJ2453维护队列&&BZOJ2120数颜色

    2016-05-28 11:20:22 共同的思路: 维护某种颜色上一次在哪里出现pre,可以知道当pre<询问的l时更新答案 块内按照pre排序 修改的时候重新O(n)扫一遍,如果和之前的不一 ...

  8. bzoj2120: 数颜色(BIT套主席树+set/分块)

    带修改的 HH的项链. 带修改考虑用BIT套主席树,查区间里有几个不同的数用a[i]上次出现的位置pre[i]<l的数有几个来算就好了. 考虑怎么修改.修改i的时候,我们需要改变i同颜色的后继的 ...

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

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

随机推荐

  1. Mecanim的Retargeting和BodyMask

    Retargeting(动画重定向) 文档 http://game.ceeger.com/Manual/Retargeting.html 介绍 Mecanim 的最强大的功能之一,重定目标的仿人机器人 ...

  2. Spring MVC之cookies跟session 数据绑定

    在我最早接触web开发的中学时代,学习的asp技术对于session的概念其实很清楚 Session("username")="张三"下次要用的时候,直接用se ...

  3. html和css知识总结

    今天把整个html和css的总结了一遍.可能还有疏忽之处,共同学习吧 [行为样式三者分离] 不加行内css样式,不加行内js效果 [标签]1>单标签<!doctype html> 文 ...

  4. scanf和cin的差异

    scanf和cin的差异 引例:http://www.cnblogs.com/shenben/p/5516996.html 大家都知道,在C++中有两种输入.输出方式—scanf和cin,但是,它们之 ...

  5. usb驱动开发11之设备生命线

    暂时先告别媒人,我们去分析各自的生命旅程,最后还会回到usb_device_match函数. 首先当你将usb设备连接在hub的某个端口上,hub检测到有设备连接了进来,它会为设备分配一个struct ...

  6. 取消StringGrid的自动滚动

    StringGrid的Options的goRowSelect为false时,在点击右侧未显示完全的Cell,StringGrid会自动向左滚动,怎样设定,取消StringGrid的自动滚动啊?Delp ...

  7. 思科简单教程CCNA

    这是CCNA的内容,从PC配置交换机(或者路由器),这里呢我们使用的软件叫pack 这是ciso开发的一款工具,能生动形象的模拟现实生活中组网技术的过程,下面我大概讲一下流程,想更多的了解我会录制一些 ...

  8. Anaroid WebView 的属性汇总

    1. 打开网页时不调用系统浏览器, 而是在本WebView中显示: mWebView.setWebViewClient(new WebViewClient(){ @Override public bo ...

  9. ant exec

    http://ant.apache.org/manual/Tasks/exec.html Exec Description Executes a system command. When the os ...

  10. [CareerCup] 8.2 Call Center 电话中心

    8.2 Imagine you have a call center with three levels of employees: respondent, manager, and director ...