题目描述
样例输入
2 3
1 2
Q 1 2
R 1 2
Q 1 2
样例输出
2
1
题目分析
首先它是一个离线莫队(在线超时QAQ)
离线首先存下它所有的询问和修改,分别存,询问要存下是第几次,以便后续输出,还要存下时间是第几个命令,比较询问和修改的时间,相应的变换颜色,最后整体输出
#include<bits/stdc++.h>
using namespace std;
const int maxn=133340;
const int maxm=1e6+10;
int a[maxn],n,m;
int l=1,r,col[maxm],ans,cnt[maxn],sq;
int bl[maxn];
struct node
{
int l,r,id,t;
}q[maxn];
struct stu
{
int pos,col,t;
}rp[maxn];
bool cmp(node A,node B)
{
if(bl[A.l]!=bl[B.l]) return bl[A.l]<bl[B.l];
if(bl[A.r]!=bl[B.r]) return bl[A.r]>bl[B.r];
return A.t<B.t;
}
void add(int x)
{
if(!col[x]) ans++;
col[x]++;
}
void del(int x)
{
col[x]--;
if(!col[x]) ans--;
}
int main()
{
scanf("%d%d",&n,&m);
sq=pow(n,2.0/3.0);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
bl[i]=i/sq+1;
}
int x,y,t=0;
int xg=0,cx=0;
char ch;
for(int i=1;i<=m;i++)
{
scanf(" %c %d%d",&ch,&x,&y);
if(ch=='Q') cx++,q[cx]=node{x,y,cx,xg};
else xg++,rp[xg]=stu{x,y,xg};
}
sort(q+1,q+1+cx,cmp);
for(int i=1;i<=cx;i++)
{
while(q[i].l<l)
{
l--;
add(a[l]);
}
while(q[i].l>l)
{
del(a[l]);
l++;
}
while(q[i].r<r)
{
del(a[r]);
r--;
}
while(q[i].r>r)
{
r++;
add(a[r]);
}
while(q[i].t>t)
{
t++;
if(rp[t].pos>=l&&rp[t].pos<=r)
{
del(a[rp[t].pos]);
add(rp[t].col);
}
swap(a[rp[t].pos],rp[t].col);
}
while(q[i].t<t)
{
if(rp[t].pos>=l&&rp[t].pos<=r)
{
del(a[rp[t].pos]);
add(rp[t].col);
}
swap(a[rp[t].pos],rp[t].col);
t--;
}
cnt[q[i].id]=ans;
}
for(int i=1;i<=cx;i++)
{
printf("%d\n",cnt[i]);
}
return 0;
}
标签:node,rp,分块,队列,bl,pos,int,maxn,莫队
From: https://www.cnblogs.com/cuichenxi/p/18152520