P1903 [国家集训队]数颜色

题意

带修莫队与普通莫队的区别在于加入了一个时间轴,具体可以看这篇博客

另外,这是卡常神题。

code:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC target("sse3","sse2","sse")
#pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
#pragma GCC target("f16c")
#pragma GCC target("fma","avx2")
#pragma GCC target("xop","fma4")
#pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector")
#pragma GCC diagnostic error "-fwhole-program"
#pragma GCC diagnostic error "-fcse-skip-blocks"
#pragma GCC diagnostic error "-funsafe-loop-optimizations"
#include<bits/stdc++.h>
using namespace std;
#define re register
const int maxn=150010;
const int maxm=150010;
int n,m,cnt1,cnt2,nowtim,nowl=1,nowr,nowans;
int a[maxn],b[maxn],pos[maxn],cnt[1000010],ans[maxm];
struct Query{int tim,l,r,id;}qr[maxm];
struct Change{int pos,last,now;}ctim[maxm];
inline bool cmp(Query x,Query y){return pos[x.l]==pos[y.l]?(pos[x.r]==pos[y.r]?x.tim<y.tim:x.r<y.r):x.l<y.l;}
inline int read()
{
	char c=getchar();re int res=0,f=1;
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
	return res*f;
}
inline void add(int x)
{
	cnt[x]++;
	if(cnt[x]==1)nowans++;
}
inline void del(int x)
{
	cnt[x]--;
	if(!cnt[x])nowans--;
}
inline void move(int pos,int k)
{
	if(pos>=nowl&&pos<=nowr)del(a[pos]),a[pos]=k,add(a[pos]);
	a[pos]=k;
}
int main()
{
	n=read(),m=read();
	for(re int i=1;i<=n;i++)a[i]=b[i]=read();
	for(re int i=1;i<=m;i++)
	{
		char op[10];scanf("%s",op);
		re int x=read(),y=read();
		if(op[0]=='Q')qr[++cnt1]=(Query){cnt2,x,y,cnt1};
		else ctim[++cnt2]=(Change){x,b[x],y},b[x]=y;
	}
	re int t=pow(n,1.0*5/7);
	for(re int i=1;i<=n;i++)pos[i]=(i-1)/t+1;
	sort(qr+1,qr+cnt1+1,cmp);
	for(re int i=1;i<=cnt1;i++)
	{
		while(nowtim<qr[i].tim)move(ctim[nowtim+1].pos,ctim[nowtim+1].now),nowtim++;
		while(nowtim>qr[i].tim)move(ctim[nowtim].pos,ctim[nowtim].last),nowtim--;
		while(nowl>qr[i].l)add(a[--nowl]);
		while(nowl<qr[i].l)del(a[nowl++]);
		while(nowr>qr[i].r)del(a[nowr--]);
		while(nowr<qr[i].r)add(a[++nowr]);
		ans[qr[i].id]=nowans;
	}
	for(re int i=1;i<=cnt1;i++)printf("%d\n",ans[i]);
	return 0;
}
posted @ 2019-12-24 08:55  nofind  阅读(124)  评论(0编辑  收藏  举报