洛谷 P1903 [國家集訓隊]數顏色 / 維護隊列 /【模板】帶修莫隊

傳送門

這道題需要我們在查詢的時候修改內容,但是我們可以對其加一個時間戳,把每次的修改都記錄一下,如果時間晚了就改回去,反之一樣

然後其他的操作就和普通的沒多大區別了,直接上代碼(記得開O2)

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
struct node {
	int l,r,time,id;
} t[maxn<<2];
struct date {
	int pos,color,last;
} ct[maxn<<2];
int a[maxn],cnt[maxn<<1],ans[maxn],belong[maxn];
int cntq=0,cntt=0;
int cmp(node x,node y) {
	return (belong[x.l] ^ belong[y.l]) ? belong[x.l] < belong[y.l] : ((belong[x.r] ^ belong[y.r]) ? belong[x.r]<belong[y.r] : x.time<y.time);
}
inline int read() {
	int res = 0;
	char c = getchar();
	while((c) < '0' || (c) > '9') c = getchar();
	while((c) >= '0' && (c) <= '9') res = (res << 1) + (res << 3) + (c ^ 48), c = getchar();
	return res;
}
int main() {
	int n,m;
	cin>>n>>m;
	int size=pow(n,2.0/3.0);
	int bnum=ceil((double)n/size);
	for(int i=1; i<=bnum; i++)
		for(int j=(i-1)*size+1; j<=i*size; j++)	belong[j]=i;
	for(int i=1; i<=n; i++)a[i]=read();
	for(int i=0; i<m; i++) {
		char opt[100];
		scanf("%s",opt);
		if(opt[0]=='Q') {
			t[++cntq].l=read();
			t[cntq].r=read();
			t[cntq].time=cntt;
			t[cntq].id=cntq;
		} else if(opt[0]=='R') {
			ct[++cntt].pos=read();
			ct[cntt].color=read();
		}
	}
	sort(t+1,t+cntq+1,cmp);
	int l=1,r=0,time=0,now=0;
	for(int i=1; i<=cntq; i++) {
		int ql=t[i].l,qr=t[i].r,qt=t[i].time;
		while(l<ql)now -= !--cnt[a[l++]];
		while(l>ql)now += !cnt[a[--l]]++;
		while(r<qr)now += !cnt[a[++r]]++;
		while(r>qr)now -= !--cnt[a[r--]];
		while(time < qt) {
			++time;
			if(ql <= ct[time].pos && ct[time].pos <= qr) now -= !--cnt[a[ct[time].pos]] - !cnt[ct[time].color]++;
			swap(a[ct[time].pos], ct[time].color);
		}
		while(time > qt) {
			if(ql <= ct[time].pos && ct[time].pos <= qr) now -= !--cnt[a[ct[time].pos]] - !cnt[ct[time].color]++;
			swap(a[ct[time].pos], ct[time].color);
			--time;
		}
		ans[t[i].id] = now;
	}
	for(int i=1; i<=cntq; i++) printf("%d\n",ans[i]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章