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。
这道题可以用带修改的莫队解决,带修改莫队是在普通莫队上加一维时间,排序时在块和右端点相同时比较询问时间,带修改莫队中的块大小为,复杂度为,下面是程序:
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#define Q(n) (int)(n*1.0/m+0.999999)
using namespace std;
const int N=50005;
struct question{
int l,r,i,q,s,t;
bool operator <(const question &p)const{
return q==p.q?r==p.r?t<p.t:q&1?r<p.r:r>p.r:q<p.q;
}
}x[N];
struct cha{
int i,x,y,l;
}y[N];
int n,m,q,s,a[N],k,p,t[1000005];
inline void read(int &s){
s=0;
char c=getchar();
while(!isdigit(c)){
c=getchar();
}
while(isdigit(c)){
s=(s<<3)+(s<<1)+c-'0';
c=getchar();
}
}
bool cmp(question a,question b){
return a.i<b.i;
}
char ch(){
char c=getchar();
while(c!='Q'&&c!='R'){
c=getchar();
}
return c;
}
void add(int x){
s+=!t[x];
++t[x];
}
void del(int x){
--t[x];
s-=!t[x];
}
int main(){
int i,l,r,ti;
read(n),read(q);
m=pow(n,2.0/3);
for(i=1;i<=n;i++){
read(a[i]);
}
for(i=1;i<=q;i++){
if(ch()=='Q'){
++k;
read(x[k].l),read(x[k].r);
x[k].q=Q(x[k].l);
x[k].i=i;
x[k].t=p;
x[k].s=0;
}
else{
++p;
y[p].i=i;
read(y[p].x),read(y[p].y);
y[p].l=a[y[p].x];
a[y[p].x]=y[p].y;
}
}
for(i=p;i>=1;i--){
a[y[i].x]=y[i].l;
}
y[p+1].i=1<<30;
sort(x+1,x+k+1);
l=r=ti=0;
for(i=1;i<=k;i++){
while(r<x[i].r){
add(a[++r]);
}
while(r>x[i].r){
del(a[r--]);
}
while(l<x[i].l){
del(a[l++]);
}
while(l>x[i].l){
add(a[--l]);
}
while(ti<x[i].t){
++ti;
if(y[ti].x>=l&&y[ti].x<=r){
del(y[ti].l);
add(y[ti].y);
}
a[y[ti].x]=y[ti].y;
}
while(ti>x[i].t){
if(y[ti].x>=l&&y[ti].x<=r){
del(y[ti].y);
add(y[ti].l);
}
a[y[ti].x]=y[ti].l;
--ti;
}
x[i].s=s;
}
sort(x+1,x+k+1,cmp);
for(i=1;i<=k;i++){
printf("%d\n",x[i].s);
}
return 0;
}