关于蓝书写法 TLE 这件事
查看原帖
关于蓝书写法 TLE 这件事
482610
Mortidesperatslav楼主2024/5/8 21:06

我的代码时间轴上单次修改应该是 O(1)O(1) 的,然而 T 了几个点,而且好像超时很多。

这是为什么呢?

#include<bits/stdc++.h>
using namespace std;
int n, m, qn, cn, kc, ks, c[140005], cc[140005], kl[3005], kr[3005], cnt[1000005];
struct que{
	int l, r, t, id;
	int ans;
}q[140005];
struct chg{
	int x, pc, nc, id;
}ch[140005];
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[i].pc = cc[ch[i].x];
		cc[ch[i].x] = ch[i].nc;
	}
	sort(q + 1, q + qn + 1, [](que a, que b){return a.l < b.l;});
	kc = pow(qn, 0.666) + 1, ks = ceil(qn * 1.00 / kc) + 0.114514;
	for (int i = 1; i <= ks; i++){
		kl[i] = kc * (i - 1) + 1;
	}
	kl[ks + 1] = qn + 1;
	for (int i = 1; i <= qn; i++)
		q[i].t = find(q[i].id);
	for (int i = 1; i <= ks; i++)
		sort(q + kl[i], q + kl[i + 1], [](que a, que b){return a.r != b.r ? a.r < b.r : a.t < b.t;});
	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 < kl[i + 1]; 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 (!(ch[k].x >= q[j - 1].l && ch[k].x <= q[j - 1].r))
						continue;
					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 - 1].t; k > q[j].t; k--){
					cc[ch[k].x] = ch[k].pc;
					if (!(ch[k].x >= q[j - 1].l && ch[k].x <= q[j - 1].r))
						continue;
					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/5/8 21:06
加载中...