MnZn刚学回滚莫队,WA on #4求调
查看原帖
MnZn刚学回滚莫队,WA on #4求调
551861
strcmp楼主2022/5/1 08:47

rt,三个样例全过,盲猜是分块的问题,谢了。

#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int maxn = 2e5 + 10;
ll now = 0, cnt[maxn], ans[maxn], a[maxn], b[maxn];
int n, m, bh[maxn], L[maxn], R[maxn], id[maxn];
struct query {
	int l, r, id;
	bool operator<(const query& a) { return bh[l] != bh[a.l] ? bh[l] < bh[a.l] : r < a.r; }
}q[maxn];
inline void add(int x) { 
	now = max(now, a[x] * (++cnt[id[x]]));
}
int k[maxn];
ll solve(int l, int r) {
	ll dis = 0;
	for (int i = l; i <= r; i++)++k[id[i]];
	for (int i = l; i <= r; i++)dis = max(dis, a[i] * k[id[i]]);
	for (int i = l; i <= r; i++)--k[id[i]];
	return dis;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(); cout.tie();
	cin >> n >> m;
	int block = sqrt(n), all = ceil(n / block);
	for (int i = 1; i <= n; i++) { 
		cin >> a[i]; b[i] = a[i];
	}
	sort(b + 1, b + 1 + n);
	int d = n; d = unique(b + 1, b + 1 + n) - b;
	for (int i = 1; i <= n; i++) { 
		id[i] = lower_bound(b + 1, b + 1 + d, a[i]) - b;
	}
	for (int i = 1; i <= n; i++)bh[i] = (i - 1) / block + 1;
	for (int i = 1; i <= all; i++) {
		L[i] = R[i - 1] + 1, R[i] = L[i] + block;
		if (R[i] > n) { R[i] = n; break; }
	}
	for (int i = 1; i <= m; i++) { cin >> q[i].l >> q[i].r; q[i].id = i; }
	int l, r, right; int last = 0;
	sort(q + 1, q + 1 + m); ll tmp = 0;
	for (int i = 1; i <= m; i++) {
		if (q[i].r - q[i].l <= block) {
			ans[q[i].id] = solve(q[i].l, q[i].r);
			continue;
		}
		l = R[bh[q[i].l]] + 1;
		if (bh[q[i].l] != last) {
			for (int i = 1; i <= n; i++)cnt[i] = 0;
			right = r = R[bh[q[i].l]];
			tmp = now = 0;
		}
		while (r < q[i].r)add(++r);
		tmp = now;
		while (l > q[i].l)add(--l);
		ans[q[i].id] = now;
		now = tmp;
		while (l <= right)--cnt[id[l++]];
		last = bh[q[i].l];
	}
	for (int i = 1; i <= m; i++)cout << ans[i] << endl;
	return 0;
}
2022/5/1 08:47
加载中...