P1903 数颜色

P1903 数颜色

Description

对于每个位置,有颜色。有两个操作,修改当前位置颜色、查询 [L,R] 区间内颜色种类数。

Solution

我们考虑带修莫队。
由于询问都是按照莫队排序,所以未必按照时间轴排序,我们考虑记下当前询问的最新修改时间戳,而后我们对于这样一个时间戳进行还原。

Code

#include<bits/stdc++.h>
using namespace std;

const int N=1e6+8;

int n,m,len;
int col[N];
int belongs[N];
char op;
int cntq,cntp;
int res[N];
int ans;
int cnt[N];
int l,r,t;

struct node1{
  int l,r,t,id;
  friend bool operator < (node1 a,node1 b){
    return belongs[a.l]==belongs[b.l]?belongs[a.r]==belongs[b.r]?a.t<b.t:belongs[a.r]<belongs[b.r]:belongs[a.l]<belongs[b.l];
  }
}Q[N];

struct node2{
  int pos,col;
}P[N];

void add(int x){if(!cnt[x])ans++;cnt[x]++;}

void del(int x){cnt[x]--;if(!cnt[x])ans--;}

void upd(node1 q,node2 &p){
  if(q.l<=p.pos&&p.pos<=q.r) del(col[p.pos]),add(p.col);
  swap(col[p.pos],p.col);
}

void solve(node1 q){
  while(l>q.l) add(col[--l]);
  while(r<q.r) add(col[++r]);
	while(l<q.l) del(col[l++]);
	while(r>q.r) del(col[r--]);
	while(t<q.t) upd(q,P[++t]);
	while(t>q.t) upd(q,P[t--]);
	res[q.id]=ans;
}

int main(){
  scanf("%d%d",&n,&m);
  len=pow(n,0.666);
  for(int i=1;i<=n;i++) scanf("%d",&col[i]),belongs[i]=(i-1)/len+1;
  for(int i=1;i<=m;i++){
    scanf("%s",&op);
    if(op=='Q') cntq++,scanf("%d%d",&Q[cntq].l,&Q[cntq].r),Q[cntq].t=cntp,Q[cntq].id=cntq;
    else cntp++,scanf("%d%d",&P[cntp].pos,&P[cntp].col);
  }
  sort(Q+1,Q+1+cntq);
  l=1,r=0,t=0;
  for(int i=1;i<=cntq;i++) solve(Q[i]);
  for(int i=1;i<=cntq;i++) printf("%d\n",res[i]);
  return 0;
}
posted @   Zimo_666  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示