BZOJ2120 数颜色
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
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6
Sample Output
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 数颜色的更多相关文章
- BZOJ2120 数颜色 【带修莫队】
BZOJ2120 数颜色 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到 ...
- bzoj2120 数颜色 莫队 带修改
[bzoj2120]数颜色 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔 ...
- BZOJ2120 数颜色 【带修改莫队】
2120: 数颜色 Time Limit: 6 Sec Memory Limit: 259 MB Submit: 6579 Solved: 2625 [Submit][Status][Discus ...
- BZOJ2120 数颜色 —— 待修改莫队
题目链接:https://vjudge.net/problem/HYSBZ-2120 2120: 数颜色 Time Limit: 6 Sec Memory Limit: 259 MBSubmit: ...
- BZOJ2120 数颜色(树套树)
B. 数颜色 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令:1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色 ...
- [Bzoj2120]数颜色 (非正解 )(莫队)
2120: 数颜色 Time Limit: 6 Sec Memory Limit: 259 MBSubmit: 6286 Solved: 2489[Submit][Status][Discuss] ...
- BZOJ2453维护队列&&BZOJ2120数颜色
2016-05-28 11:20:22 共同的思路: 维护某种颜色上一次在哪里出现pre,可以知道当pre<询问的l时更新答案 块内按照pre排序 修改的时候重新O(n)扫一遍,如果和之前的不一 ...
- bzoj2120: 数颜色(BIT套主席树+set/分块)
带修改的 HH的项链. 带修改考虑用BIT套主席树,查区间里有几个不同的数用a[i]上次出现的位置pre[i]<l的数有几个来算就好了. 考虑怎么修改.修改i的时候,我们需要改变i同颜色的后继的 ...
- BZOJ2120 数颜色(带修改莫队)
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
随机推荐
- ZGrapher 画函数曲线图的工具
可以下载个绿色版,我下载的是 ZGrapher 1.4 绿色版.下面先看下图出来的图: 然后可以在“file"->"Save as Picture ..." -&g ...
- IO流的练习 —— 创建用户注册、登陆案例
把上次用集合做的时候的分析拿出来 需求: 用户登录注册案例 按照如下操作,可以让我们更符合面向对象思想: A:这个案例有哪些类 B:每个类中又有哪些东西 C:类与类之间的关系 分析: A:这个案例有哪 ...
- java 16 - 9 增强for的概述和使用
JDK5的新特性:自动拆装箱,泛型,增强for,静态导入,可变参数,枚举 增强for:是for循环的一种. 格式: for(元素数据类型 变量 : 数组或者Collection集合) { 使用变量即可 ...
- UIImageJPEGRepresentation和UIImagePNGRepresentation
UIImageJPEGRepresentation方法在耗时上比较少 而UIImagePNGRepresentation耗时操作时间比较长 -(void)imagePickerController:( ...
- AMAP
ViewController.m #import "ViewController.h" //地图显示需要的头文件 #import <MAMapKit/MAMapKit.h&g ...
- 【C#】【Thread】ManualResetEvent和AutoResetEvent区别
ManualResetEvent和AutoResetEvent主要用于线程之间同步问题. 主要使用方法有Set();Reset();WaitOne(); Set():将事件状态设置为终止状态,允许一个 ...
- android Camera 中如何修改缩放变焦参数
如何修改 zoomRatio 修改过程: 1, 先找到 gZoomRatio 数组序列的值 Location: V:\project_code\project_name\ALPS.JB.M ...
- WinForm编程数据视图之DataGridView浅析
学习C#语言的朋友们肯定或多或少地接触到了WinForm编程,在C#语言的可视化IDE中(如VS.NET中)使用设计器可以让我们轻松地完成窗体.按钮.标签.图片框等等控件的组合,我们可以轻易地做出界面 ...
- WCF4.0 –- RESTful WCF Services (1) (入门)
WCF 很好的支持了 REST 的开发, 而 RESTful 的服务通常是架构层面上的考虑. 因为它天生就具有很好的跨平台跨语言的集成能力,几乎所有的语言和网络平台都支持 HTTP 请求,无需去实现复 ...
- 封装WCF客户端调用
在之前的博客中,我记录过如何利用SvcUtil.exe工具生成客户端的代理文件,然后调用的情形. 今天我要讲解的是利用代码直接对服务端进行调用.好处在于,一是不会生成那么大的引用文件,其次是可以方便控 ...