题意

给出n个数字和m个操作。操作有两种。1:查询区间[l,r]内不同种类得数字个数。2: 将下标为p得数字修改为v

分析

如果不是修改操作的话,用莫队贼简单就可以水过,但是因为带了修改就有一些麻烦了。

分块

 开一个数组pre[i]记录上一个和第i个元素相同元素得位置。那么对于区间[l,r],当pre[i]<l的时候,ans++。完整块内就可以直接二分查找,不完整块直接暴力。修改是直接暴力修改因为它保证修改操作不会超过1000次。

下面是代码

  

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
const int maxn=+;
int a[maxn],belong[maxn],L[maxn],R[maxn],pre[maxn];
int last[+],b[maxn]; int n,m,cnt,block;
void update(int p,int v){
for(int i=;i<=n;i++)
last[a[i]]=;
a[p]=v;
for(int i=;i<=n;i++){
b[i]=last[a[i]];
last[a[i]]=i;
}
for(int i=;i<=cnt;i++){
for(int j=L[i];j<=R[i];j++)
pre[j]=b[j];
sort(pre+L[i],pre+R[i]+);
}
}
int Find(int p,int v){
int res=;
int l=L[p],r=R[p];
while(l<=r){
int m=l+(r-l)/;
if(pre[m]<v){
res=m;
l=m+;
}else{
r=m-;
}
}
return res-L[p]+;
} int query(int l,int r){
int res=;
if(belong[l]==belong[r]){
for(int i=l;i<=r;i++){
if(b[i]<l)
res++;
}
return res;
}
for(int i=l;i<=R[belong[l]];i++)
if(b[i]<l)
res++; for(int i=L[belong[r]];i<=r;i++)
if(b[i]<l)
res++; for(int i=belong[l]+;i<belong[r];i++){
res+=Find(i,l);
}
return res;
} int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
b[i]=last[a[i]];
last[a[i]]=i;
}
block=sqrt(n);cnt=n/block;
if(n%block)cnt++;
for(int i=;i<=n;i++)
belong[i]=(i-)/block+;
for(int i=;i<=cnt;i++)
L[i]=(i-)*block+,R[i]=i*block;
R[cnt]=n; for(int i=;i<=cnt;i++){
for(int j=L[i];j<=R[i];j++)
pre[j]=b[j];
sort(pre+L[i],pre+R[i]+);
}
char c;
int l,r;
for(int i=;i<=m;i++){
scanf(" %c",&c);
if(c=='Q'){
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r));
}else{
scanf("%d%d",&l,&r);
update(l,r);
}
}
return ;
}

莫队

  对于莫队来说,难点就在于它带有修改操作。我们怎么来处理修改呢?我们在除了l,r指针以外再增加一个指针now,用类似l和r得方式进行维护。

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath> using namespace std;
const int maxn=+;
int belong[maxn],val[maxn];
struct Node{
int L,R,id,tim;
bool operator<(const Node& rhs)const{
return belong[L]==belong[rhs.L]?(belong[R]==belong[rhs.R]?tim<rhs.tim:R<rhs.R):L<rhs.L;
}
int ans;
}ask[maxn];
struct Up{
int p,v,z;
}up[maxn];
int num1,num2;
int cmp(Node a,Node b){
return a.id<b.id;
}
int n,q;
int f[+],ans,block,l,r,now;
void update(int p,int addv){
if(addv>){
f[val[p]]++;
if(f[val[p]]==)
ans++;
}else{
f[val[p]]--;
if(f[val[p]]==)
ans--;
}
}
void in_time(int x){
if(up[x].p>=l&&up[x].p<=r){
update(up[x].p,-);
}
up[x].z=val[up[x].p];
val[up[x].p]=up[x].v;
if(up[x].p>=l&&up[x].p<=r){
update(up[x].p,);
}
}
void out_time(int x){
if(up[x].p>=l&&up[x].p<=r)
update(up[x].p,-);
val[up[x].p]=up[x].z;
if(up[x].p>=l&&up[x].p<=r)
update(up[x].p,);
} void solve(){
l=,r=,now=;
for(int i=;i<=num1;i++){
if(r<ask[i].R){
for(r=r+;r<ask[i].R;r++)
update(r,);
update(r,);
}
if(l>ask[i].L){
for(l=l-;l>ask[i].L;l--)
update(l,);
update(l,);
}
if(r>ask[i].R){
for(;r>ask[i].R;r--)
update(r,-);
}
if(l<ask[i].L){
for(;l<ask[i].L;l++)
update(l,-);
}
if(now<ask[i].tim){
for(now=now+;now<ask[i].tim;now++)
in_time(now);
in_time(now);
}
if(now>ask[i].tim){
for(;now>ask[i].tim;now--)
out_time(now);
}
ask[i].ans=ans;
}
} int main(){
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++){
scanf("%d",&val[i]);
}
block=sqrt(n);
for(int i=;i<=n;i++)
belong[i]=(i-)/block+;
char c;
int l,r;
for(int i=;i<=q;i++){
scanf(" %c",&c);
if(c=='Q'){
num1++;
scanf("%d%d",&ask[num1].L,&ask[num1].R);
ask[num1].id=num1;ask[num1].tim=num2;
}else{
num2++;
scanf("%d%d",&up[num2].p,&up[num2].v);
up[num2].z=;
}
}
sort(ask+,ask++num1);
solve();
sort(ask+,ask++num1,cmp);
for(int i=;i<=num1;i++)
printf("%d\n",ask[i].ans); return ;
}

【BZOJ 2120】数颜色【分块/莫队】的更多相关文章

  1. BZOJ 2120: 数颜色 分块

    2120: 数颜色 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php? ...

  2. Bzoj 2453: 维护队列 && Bzoj 2120: 数颜色 分块,bitset

    2453: 维护队列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 578  Solved: 247[Submit][Status][Discuss] ...

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

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

  4. Bzoj 2120: 数颜色 && 2453: 维护队列 莫队,分块,bitset

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

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

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

  6. BZOJ 2120 数颜色 【带修改莫队】

    任意门:https://www.lydsy.com/JudgeOnline/problem.php?id=2120 2120: 数颜色 Time Limit: 6 Sec  Memory Limit: ...

  7. BZOJ 2120: 数颜色

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

  8. bzoj 2120 数颜色 题解

    转载请注明:http://blog.csdn.net/jiangshibiao/article/details/23990489 [原题] 2120: 数颜色 Time Limit: 6 Sec  M ...

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

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

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

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2120 [题目大意] 给出一颜色序列,每次可以修改一个位置的颜色或者询问一个区间不同颜色 ...

随机推荐

  1. spring深入内容

    https://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/index.html

  2. 优化RequireJS项目(合并与压缩)

    关于RequireJS已经有很多文章介绍过了.这个工具可以将你的JavaScript代码轻易的分割成苦 干个模块(module)并且保持你的代码模块化与易维护性.这样,你将获得一些具有互相依赖关系的J ...

  3. cocos2d

    http://www.jetbrains.com/webstorm/download/index.html 运行又有下面错误 Fatal signal 11 (SIGSEGV) at 0x000000 ...

  4. CentOS部署NetCore - 3. 部署站点

    一. CentOS 安装FTP linux 安装 ftp第一步 使用如下命令#rpm -qa |grep vsftpd可以检测出是否安装了vsftpd软件, 如果没有安装,使用YUM命令进行安装. y ...

  5. JEECG获取当前登录人的值

    TSUser user = ResourceUtil.getSessionUserName(); mv.addObject("fbillerid", user.getUserNam ...

  6. 软RAID 0的技术概要及实现

    1 什么是RAID,RAID的级别和特点 : 什么是RAID呢?全称是 “A Case for Redundant Arrays of Inexpensive Disks (RAID)”,在1987年 ...

  7. java代码------计算器

    总结:我用if()语句写计算功能的代码时,实现不了,与switch_-catch语句不一样.不知到怎么实现 package com.p; import javax.swing.*; import ja ...

  8. SQL Server 2005/2008压缩数据库日志的方法

    适用于SQL Server 2005的方法 Backup Log DNName WITH no_log GO DUMP TRANSACTION DNName WITH no_log GO USE DN ...

  9. 安装scikit-image问题

    参考地址: Image Processing Using Python https://code.tutsplus.com/tutorials/image-processing-using-pytho ...

  10. JS-用法

    JavaScript 用法 HTML 中的脚本必须位于 <script> 与 </script> 标签之间. 脚本可被放置在 HTML 页面的 <body> 和 & ...