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


#include <cstdio> 
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for( register int (a) = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for( register int (a) = (b); (a) >= (c); --(a))
#define Max(a,b) ((a) >= (b) ? (a) : (b))
#define Min(a,b) ((a) <= (b) ? (a) : (b))
#define Iv inline void
#define Ii inline int
#define Il inline long long
#define ll long long
#define re register
struct ios{
	template <typename ATP> inline ios& operator >> (ATP &x) {
		x=0; int f=1; char c;
		for (c=getchar(); c<'0' || c>'9'; c=getchar()) if(c == '-') f=-1;
		while (c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c=getchar();
		x*=f;
		return *this;
	}
	template <typename ATP> inline ios& operator << (ATP x) {
		int digit = 0; char sch[67];
		if( x == 0) { putchar ('0'); return *this;}
		if (x < 0) { x = -x, putchar ('-');}
		while (x) sch[++digit]=x % 10 ^ '0', x /= 10;
		for (register int i=digit; i; --i) putchar (sch[i]);
		return *this;
	}
} io;
using namespace std;
//#define InputAndOutput_Bug_Test
#ifdef InputAndOutput_Bug_Test
int main(){
	while (1) {
		long long x;
		io >> x;
		cout << x << endl;
		io << x;
		putchar ('\n');
	}
}
#endif
const int N=50007;
int col[N];
int TotColor[1000007],NowColor[N];
int block[N];
int ans[N],Ans;
int l=1,r;

struct Query{
	int l,r,tim,id;
	bool operator< (const Query &b)const{
		if(block[l]==block[b.l]){
			if(block[r]==block[b.r])
				return tim<b.tim;
			else
				return r<b.r;
		}
		else
			return l<b.l;
	}
}q[N];

struct Change{
	int pos,New,Old;	
}c[N]; 

Iv Modify(int workColor,int d){
	TotColor[workColor]+=d;
	if(d>0)
		Ans+=(TotColor[workColor]==1);
	if(d<0)
		Ans-=(TotColor[workColor]==0);
}
Iv Going(int pos,int workColor){
	if(l<=pos&&pos<=r){
		Modify(workColor,1),
		Modify(col[pos],-1);
	}
	col[pos]=workColor;
}

int main(){
	int n,m; io>>n>>m;
	int unit=pow(n,0.666666);
	R(i,1,n){
		io>>col[i],
		NowColor[i]=col[i],
		block[i]=(i-1)/unit+1;
	}
	
	int tot=0,Time=0;
	R(i,1,m){
		char opt;
		for(opt=getchar();opt!='Q'&&opt!='R';opt=getchar());
		if(opt=='Q'){
			int l,r;
			io>>l>>r,
			q[++tot]=(Query){l,r,Time,tot};
		}
		else{
			int pos,newColor;
			io>>pos>>newColor,
			c[++Time]=(Change){pos,newColor,NowColor[pos]},
			NowColor[pos]=newColor;
		}
	}
	
	sort(q+1,q+tot+1);
	Time=0;
	R(i,1,tot){
		while(Time<q[i].tim) Going(c[Time+1].pos,c[Time+1].New),++Time;
		while(Time>q[i].tim) Going(c[Time].pos,c[Time].Old),--Time;
		while(l<q[i].l) Modify(col[l],-1),++l;
		while(l>q[i].l) Modify(col[l-1],1),--l;
		while(r<q[i].r) Modify(col[r+1],1),++r;
		while(r>q[i].r) Modify(col[r],-1),--r;
		
		ans[q[i].id]=Ans;
	} 
	
	R(i,1,tot){
		io<<ans[i],
		putchar('\n');
	
	}
	
	return 0;
} 

posted @ 2019-06-22 20:38  邱涵的秘密基地  阅读(124)  评论(0编辑  收藏  举报