关于TLE
查看原帖
关于TLE
482610
Mortidesperatslav楼主2024/5/12 20:54

卡常大师天波去打 ARC 了,只有我被这道紫题卡常,照着 OIwiki 学了半天收获 TLE*14。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n, m;
struct que {
	int l, r, id;
	long long ans;
} q[100005];
int a[100005], bel[100005];
int kl[1005], kr[1005], ks, kc;
int ml[1005], mr[1005], ms, mc;
long long nans, lans;
map<int, int> cnt, ccnt;
void BuildN() {
	kc = sqrt(n), ks = ceil(n / kc) + 0.114514;//+0.114514 防止浮点数误差
	for (int i = 1; i <= ks; i++)
		kl[i] = kr[i - 1] + 1, kr[i] = kl[i] + kc - 1;
	kr[ks] = n;//对原序列进行第一次分块
	for (int i = 1; i <= ks; i++)
		for (int j = kl[i]; j <= kr[i]; j++)
			bel[j] = i;//处理出每个数所在块,此后就可以进行回滚
	//至此,原序列完成了简单的分块
}
void BuildQ() {
	mc = sqrt(n), ms = ceil(m / mc) + 0.114514;
	for (int i = 1; i <= ms; i++)
		ml[i] = mr[i - 1] + 1, mr[i] = ml[i] + mc - 1;
	mr[ms] = m;
	sort(q + 1, q + 1 + m, [](que &a, que &b){
		\
		return bel[a.l] != bel[b.l] ? bel[a.l] < bel[b.l] : a.r < b.r;
		\
	});
	//对询问进行莫队分块,此时我们可以开始离线处理了
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	BuildN();
	for (int i = 1; i <= m; i++){
		cin >> q[i].l >> q[i].r;
		q[i].id = i;
	}
	BuildQ();
	int nl = 1, nr = 0, lb = 0;
	for (int i = 1; i <= m; i++){ //这不是普通的莫队了,不再以块为单位处理
		//也有可能是我的蓝书写法比较抽象,似乎也可以以块为单位
		if (bel[q[i].l] == bel[q[i].r]) { //同一块内暴力
			for (int j = q[i].l; j <= q[i].r; j++){
				ccnt[a[j]]++;
			}
			for (int j = q[i].l; j <= q[i].r; j++)
				q[i].ans = max(q[i].ans, 1ll * a[j] * ccnt[a[j]]);
			for (int j = q[i].l; j <= q[i].r; j++)
				ccnt[a[j]]--;
			continue;
			//有点回溯思想,但是不难理解
		}
		if (bel[q[i].l] != lb){
			//左端点与上一个询问左端点不同,初始化
			while (nr > kr[bel[q[i].l]])
				cnt[a[nr]]--, nr--;
			while (nl <= kr[bel[q[i].l]])
				cnt[a[nl]]--, nl++;
			nans = 0;
			lb = bel[q[i].l];
		}
		while (nr < q[i].r){
			nr++;
			cnt[a[nr]]++;
			nans = max(nans, 1ll * a[nr] * cnt[a[nr]]);
		}
		lans = nans;
		int tl = nl;
		while (tl > q[i].l){
			tl--;
			cnt[a[tl]]++;
			lans = max(lans, 1ll * a[tl] * cnt[a[tl]]);
		}
		q[i].ans = lans;
		while (tl < nl)
			cnt[a[tl]]--, tl++;
	}
	sort(q + 1, q + 1 + m, [](que a, que b){return a.id < b.id;});
	for (int i = 1; i <= m; i++)
		cout << q[i].ans << "\n";
}
2024/5/12 20:54
加载中...