MnZn第一次写带修莫队,为什么 RE 40
查看原帖
MnZn第一次写带修莫队,为什么 RE 40
482610
Mortidesperatslav楼主2024/4/22 19:20

本地开了 -Wall 和 -Wextra,没有查出警告,并且我拿基本操作和我的普通莫队对照了,应该是没问题的,修改操作是哪里写挂了/yiw

#include<bits/stdc++.h>
using namespace std;
int n, m, qn, cn, kc, ks, c[150005], cc[150005], kl[5005], kr[5005], cnt[1000005];
struct que{
	int l, r, t, id;
	int ans;
}q[150005];
struct chg{
	int x, pc, nc, id;
}ch[150005];
int find(int x){
	int l = 0, r = cn, ans = 0;
	while (l <= r){
		int mid = (l + r) >> 1;
		if (x > ch[mid].id)
			ans = mid, l = mid + 1;
		else
			r = mid - 1;
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++){
		cin >> c[i];
		cc[i] = c[i];
	}
	for (int i = 1; i <= m; i++){
		char op;
		cin >> op;
		if (op == 'Q'){
			qn++;
			cin >> q[qn].l >> q[qn].r;
			q[qn].id = i;
		}else if (op == 'R'){
			cn++;
			cin >> ch[cn].x >> ch[cn].nc;
			ch[cn].id = i;
		}
	}
	for (int i = 1; i <= cn; i++){
		ch[cn].pc = cc[ch[cn].x];
		cc[ch[cn].x] = ch[cn].nc;
	}
	sort(q + 1, q + qn + 1, [](que a, que b){return a.l < b.l;});
	kc = sqrt(qn), ks = ceil(n * 1.0 / kc) + 0.1;
	for (int i = 1; i <= ks; i++)
		kl[i] = kr[i - 1] + 1, kr[i] = kl[i] + kc - 1;
	kr[ks] = qn;
	for (int i = 1; i <= ks; i++)
		sort(q + kl[i], q + kr[i] + 1, [](que a, que b){return a.r != b.r ? a.r < b.r : a.t < b.t;});
	for (int i = 1; i <= qn; i++)
		q[i].t = find(q[i].id);
	for (int i = 1; i <= ks; i++){
		int ans = 0;
		for (int j = 1; j <= n; j++)
			cc[j] = c[j];
		memset(cnt, 0, sizeof cnt);
		for (int j = 1; j <= q[kl[i]].t; j++)
			cc[ch[j].x] = ch[j].nc;
		for (int j = q[kl[i]].l; j <= q[kl[i]].r; j++){
			if (cnt[cc[j]] == 0)
				ans++;
			cnt[cc[j]]++;
		}
		q[kl[i]].ans = ans;
		for (int j = kl[i] + 1; j <= kr[i]; j++){
			if (q[j].t > q[j - 1].t)
				for (int k = q[j - 1].t + 1; k <= q[j].t; k++){
					cc[ch[k].x] = ch[k].nc;
					if (cnt[ch[k].pc] == 1)
						ans--;
					cnt[ch[k].pc]--;
					if (cnt[ch[k].nc] == 0)
						ans++;
					cnt[ch[k].nc]++;
				}
			else
				for (int k = q[j].t + 1; k <= q[j - 1].t; k++){
					cc[ch[k].x] = ch[k].pc;
					if (cnt[ch[k].pc] == 0)
						ans++;
					cnt[ch[k].pc]++;
					if (cnt[ch[k].nc] == 1)
						ans--;
					cnt[ch[k].nc]--;
				}
			if (q[j].l > q[j - 1].l)
				for (int k = q[j - 1].l; k < q[j].l; k++){
					if (cnt[cc[k]] == 1)
						ans--;
					cnt[cc[k]]--;
				}
			else
				for (int k = q[j].l; k < q[j - 1].l; k++){
					if (cnt[cc[k]] == 0)
						ans++;
					cnt[cc[k]]++;
				}
			for (int k = q[j - 1].r + 1; k <= q[j].r; k++){
				if (cnt[cc[k]] == 0)
					ans++;
				cnt[cc[k]]++;
			}
			q[j].ans = ans;
		}
	}
	sort(q + 1, q + 1 + qn, [](que a, que b){return a.id < b.id;});
	for (int i = 1; i <= qn; i++)
		cout << q[i].ans << "\n";
	return 0;
}
2024/4/22 19:20
加载中...