P1903 [国家集训队]数颜色 / 维护队列(带修改莫队)

p1903

题意:

给你一个长度为n的序列,m次询问,每次改一个数或询问[l,r]内有几种数。

Solution

询问离线,维护l,r,id,last。last是本次询问上一次修改的时间。
多了两个while循环,恢复/修改就行了

struct Node{
	int l,r,last,id;
	bool operator < (const Node &B)const{
		if(bel[l]!=bel[B.l]) return bel[l]<bel[B.l];
		else if(bel[r]!=bel[B.r]) return bel[l]&1?bel[r]<bel[B.r]:bel[r]>bel[B.r]; // 奇偶性排序
		return bel[r]&1?last<B.last:last>B.last; // 奇偶性排序
	}
}b[maxn];
void upd(rint id,rint tid){
      if(b[id].l<=tpos[tid]&&tpos[tid]<=b[id].r){
      	    del(a[tpos[tid]]);
            add(tval[tid]);
      }
      swap(a[tpos[tid]],tval[tid]); // 改完一次后,交换一下,下次再改直接用(你很可能听不懂我在说什么,那不重要)
}
int main(){
      XXX
for(rint i=1;i<=bc;++i){
	const rint ql=b[i].l,qr=b[i].r;
	while(l<ql) del(a[l++]);
	while(l>ql) add(a[--l]);
	while(r<qr) add(a[++r]);
	while(r>qr) del(a[r--]);
	while(t>b[i].last) upd(i,t--);
	while(t<b[i].last) upd(i,++t);
	ans[b[i].id]=now;
}
    XXX
    return 0;
}
原文地址:https://www.cnblogs.com/Lour688/p/13801219.html