Description
你小时候玩过弹珠吗?
小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N。为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少。当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色。但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助。
Input
输入文件第一行包含两个整数N和M。
第二行N个整数,表示初始队列中弹珠的颜色。
接下来M行,每行的形式为“Q L R”或“R x c”,“Q L R”表示A想知道从队列第L个弹珠到第R个弹珠中,一共有多少不同颜色的弹珠,“R x c”表示A把x位置上的弹珠换成了c颜色。
Output
对于每个Q操作,输出一行表示询问结果。
Sample Input
2 3
1 2
Q 1 2
R 1 2
Q 1 2
Sample Output
2
1
1
HINT
对于100%的数据,有1 ≤ N ≤ 10000, 1 ≤ M ≤ 10000,小朋友A不会修改超过1000次,所有颜色均用1到10^6的整数表示。
Source
【教练网上分块的题解细节太多写起来太麻烦我完全实现不出啦!】
于是我用了莫队.....
多记录个时间t就行了,然后和普通莫队一样搞【糖果公园队列版】
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[10001],b[10001];
struct ask
{
int l,r;
int t,p;
int x;
}as[10001];
struct change
{
int l,x;
int la;
}ch[10001];
int belong[10001];
int s[1000001];
bool v[10001];
int nt,sx;
int ans;
inline bool cmp1(ask x,ask y)
{
if(belong[x.l]<belong[y.l])
return true;
if(belong[x.l]==belong[y.l])
{
if(x.r<y.r)
return true;
if(x.r==y.r&&x.t<y.t)
return true;
}
return false;
}
inline bool cmp2(ask x,ask y)
{
if(x.p<y.p)
return true;
return false;
}
inline void turn(int l)
{
if(v[l])
{
s[a[l]]--;
if(s[a[l]]==0)
ans--;
v[l]=false;
}
else
{
s[a[l]]++;
if(s[a[l]]==1)
ans++;
v[l]=true;
}
}
inline void adt(int t)
{
int loc=ch[t].l,co=ch[t].x;
if(v[loc])
{
s[a[loc]]--;
if(s[a[loc]]==0)
ans--;
a[loc]=co;
s[co]++;
if(s[co]==1)
ans++;
}
else
a[loc]=co;
}
inline void inct(int t)
{
int loc=ch[t].l,co=ch[t].la;
if(v[loc])
{
s[a[loc]]--;
if(s[a[loc]]==0)
ans--;
a[loc]=co;
s[co]++;
if(s[co]==1)
ans++;
}
else
a[loc]=co;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int i;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
nt=sqrt(n);
sx=(n-1)/nt+1;
for(i=1;i<=n;i++)
belong[i]=(i-1)/nt+1;
int p1=0,p2=0;
char x[4];
for(i=1;i<=m;i++)
{
scanf("%s",x);
if(x[0]=='Q')
{
p1++;
scanf("%d%d",&as[p1].l,&as[p1].r);
as[p1].t=p2;
as[p1].p=p1;
}
else
{
p2++;
scanf("%d%d",&ch[p2].l,&ch[p2].x);
ch[p2].la=b[ch[p2].l];
b[ch[p2].l]=ch[p2].x;
}
}
sort(as+1,as+1+p1,cmp1);
int l=1,r=0,t=0;
for(i=1;i<=m;i++)
{
while(l<as[i].l)
{
turn(l);
l++;
}
while(l>as[i].l)
{
l--;
turn(l);
}
while(r<as[i].r)
{
r++;
turn(r);
}
while(r>as[i].r)
{
turn(r);
r--;
}
while(t<as[i].t)
{
t++;
adt(t);
}
while(t>as[i].t)
{
inct(t);
t--;
}
as[i].x=ans;
}
sort(as+1,as+1+p1,cmp2);
for(i=1;i<=p1;i++)
printf("%d\n",as[i].x);
return 0;
}