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. 台北Unity开发者研讨会 笔记

    本文转自:http://ndark.wordpress.com/2013/05/12/20130511-台北unity开发者研讨会-笔记/ (墙外) 说明 本文单纯只是笔记,若有笔误敬请见谅. 相关参 ...

  2. 转: EclipseIDE开发 for C++

    Eclipse 开发C++ 程序 http://tangmingjie2009.iteye.com/blog/2088363 Eclipse 开发C++ 程序 (二) 静态库 http://tangm ...

  3. Java的IO操作---File类

    目标 1)掌握File类作用 2)可以使用file类中方法对文件进行读写操作. File类 唯一与文件有关的类.使用file类可进行创建或删除操作,要想使用File类,首先观察File类的构造方法. ...

  4. 安卓版微信内置浏览器,<a href="tel:电话号码"></a> 这个链接失效,不能跳到拨号界面?

    https://segmentfault.com/q/1010000000318831 在URL最后面加“ #mp.weixin.qq.com ”,应该加其他qq.com的二级域名都行,估计是微信的安 ...

  5. Spring之AOP

    package org.zln.module.test3_aop.interceptor; import org.aspectj.lang.ProceedingJoinPoint; import or ...

  6. Python基础 - 获取N天前的日期

    获取今天前第N天的日期 from datetime import datetime from datetime import timedelta def get_date(days=N): retur ...

  7. Caffe学习系列(18): 绘制网络模型

    python/draw_net.py, 这个文件,就是用来绘制网络模型的.也就是将网络模型由prototxt变成一张图片. 在绘制之前,需要先安装两个库 1.安装GraphViz # sudo apt ...

  8. pythonchallenge(二)

    PythonChallenge_2 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou,密码shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux ...

  9. [30分钟]MSSQL快速入门教程

    1.什么是SQL语句 sql语言:结构化的查询语言.(Structured Query Language),是关系数据库管理系统的标准语言. 它是一种解释语言:写一句执行一句,不需要整体编译执行.语法 ...

  10. IT男的”幸福”生活"续9

    世界上最容易失去的便是时间了,我们总是蓦然回首,而时间早已流去. 曾经的种种,时时刻刻在我们脑中出现,让我们感到开心,快乐,幸福等. 有时好想有一种动冲,回到过去,再感受一下心中的那份触动. 又一年过 ...