数颜色「国家集训队」

题意

待修莫队模板题


思路

待修莫队在普通莫队的基础上,额外维护一个修改操作,每一次根据查询操作的时间加入修改或是撤销修改。

实现蛮显然的,配合代码很容易搞懂。

note:块大小的证明参见这里,此处不做赘述。

代码

#include <bits/stdc++.h>

using namespace std;

namespace StandardIO {

	template<typename T>inline void read (T &x) {
		x=0;T f=1;char c=getchar();
		for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
		for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
		x*=f;
	}

	template<typename T>inline void write (T x) {
		if (x<0) putchar('-'),x*=-1;
		if (x>=10) write(x/10);
		putchar(x%10+'0');
	}

}

using namespace StandardIO;

namespace Project {
	
	const int N=200200;
	
	int n,m,block;
	int a[N];
	int qcnt,ucnt;
	struct ask {
		int l,r,t,id;
	} q[N];
	struct upd {
		int x,pre,now;
	} u[N];
	int cnt[1000001],ans[N],res;
	
	inline bool cmp (const ask x,const ask y) {
		return (x.l/block!=y.l/block)?(x.l/block<y.l/block):((x.r/block!=y.r/block)?(x.r/block<y.r/block):x.t<y.t);
	}

	inline void MAIN () {
		read(n),read(m);
		for (register int i=1; i<=n; ++i) 
			read(a[i]);
		for (register int i=1; i<=m; ++i) {
			scanf("\n");
			if (getchar()=='Q') {
				++qcnt,read(q[qcnt].l),read(q[qcnt].r),q[qcnt].t=ucnt,q[qcnt].id=qcnt;
			} else {
				++ucnt,read(u[ucnt].x),read(u[ucnt].now),u[ucnt].pre=a[u[ucnt].x],a[u[ucnt].x]=u[ucnt].now;
			}
		}
		for (register int i=ucnt; i; --i) 
			a[u[i].x]=u[i].pre;
		block=ceil(exp((log(n)+log(ucnt))/3)),sort(q+1,q+qcnt+1,cmp);
		int l=1,r=0,t=0;
		for (register int i=1; i<=qcnt; ++i) {
			while (l>q[i].l) res+=!cnt[a[--l]]++;
			while (l<q[i].l) res-=!--cnt[a[l++]];
			while (r<q[i].r) res+=!cnt[a[++r]]++;
			while (r>q[i].r) res-=!--cnt[a[r--]];
			while (q[i].t<t) {
				int x=u[t].x;
				if (l<=x&&x<=r) res-=!--cnt[a[x]];
				a[x]=u[t--].pre;
				if (l<=x&&x<=r) res+=!cnt[a[x]]++;
			}
			while (q[i].t>t) {
				int x=u[++t].x;
				if (l<=x&&x<=r) res-=!--cnt[a[x]];
				a[x]=u[t].now;
				if (l<=x&&x<=r) res+=!cnt[a[x]]++;
			}
			ans[q[i].id]=res;
		}
		for (register int i=1; i<=qcnt; ++i) {
			write(ans[i]),puts("");
		}
	}
	
}

int main () {
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	Project::MAIN();
}

posted @ 2019-10-23 22:55  Ilverene  阅读(163)  评论(0编辑  收藏  举报