Luogu P1903 [国家集训队] 数颜色 / 维护队列
Luogu P1903(带修莫队)
莫队算法是解决已知
本题除了单纯的查询
与普通的莫队算法相比,带修莫队多了一个时间轴
具体实现方式与普通莫队相同,只不过在状态转移的时候要根据时间进行修改操作,如果前者
莫队算法的时间复杂度受块长影响很大,本题中块长取
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<limits.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof(a));
using namespace std;
template<typename T> void read(T &k)
{
k=0;
T flag=1;char b=getchar();
while (b<'0' || b>'9') {flag=(b=='-')?-1:1;b=getchar();}
while (b>='0' && b<='9') {k=(k<<3)+(k<<1)+(b^48);b=getchar();}
k*=flag;
}
const int _SIZE=133333,_MAXN=1e6;
int n,m;
int a[_SIZE+5],cnt[_MAXN+5],ans[_SIZE+5];
int len,sum;
struct QUERY{
int l,r,t,id;
}que[_SIZE+5],mod[_SIZE+5];
void add(int x)
{
sum+=!cnt[x]++;
}
void del(int x)
{
sum-=!--cnt[x];
}
void update(int x,int t)
{
if (que[x].l<=mod[t].l && mod[t].l<=que[x].r)
{
del(a[mod[t].l]);
add(mod[t].r);
}
swap(a[mod[t].l],mod[t].r);
}
bool cmp(QUERY x,QUERY y)
{
if (x.l/len!=y.l/len) return x.l<y.l;
if (x.r/len!=y.r/len) return x.r<y.r;
return x.t<y.t;
}
int cntq,cntm;
int main()
{
read(n);read(m);
len=pow(n,0.66);
for (int i=1;i<=n;i++) read(a[i]);
for (int i=1;i<=m;i++)
{
char com[5];scanf("%s",com);
int _t1,_t2;read(_t1),read(_t2);
if (com[0]=='Q')
{
cntq++,
que[cntq].id=cntq,que[cntq].l=_t1,
que[cntq].r=_t2,que[cntq].t=cntm;
}
else
{
cntm++,
mod[cntm].l=_t1,mod[cntm].r=_t2;
}
}
sort(que+1,que+cntq+1,cmp);
int lcur=1,rcur=0,tcur=0;
for (int i=1;i<=cntq;i++)
{
while (lcur>que[i].l) add(a[--lcur]);
while (lcur<que[i].l) del(a[lcur++]);
while (rcur>que[i].r) del(a[rcur--]);
while (rcur<que[i].r) add(a[++rcur]);
while (tcur<que[i].t) update(i,++tcur);
while (tcur>que[i].t) update(i,tcur--);
ans[que[i].id]=sum;
}
for (int i=1;i<=cntq;i++) printf("%d\n",ans[i]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步