萌新求助回滚莫队板子题
查看原帖
萌新求助回滚莫队板子题
141599
sinsop90楼主2022/2/8 15:29
#include <bits/stdc++.h>
#define int long long
#define maxn 500005
using namespace std;
int n, q, t[maxn], a[maxn], m, sqr, chk[maxn], cnt[maxn], ansn[maxn], ans, le[maxn], ri[maxn];
int ins(int k) {
	chk[a[k]] ++;
	return chk[a[k]] * t[a[k]];
}
void del(int k) {
	chk[a[k]] --;
}
struct node {
	int l, r, id;
}Q[maxn << 1];
bool cmp(node a, node b) {
	if(cnt[a.l] == cnt[b.l]) return a.r < b.r;
	else return cnt[a.l] < cnt[b.l];
}

signed main() {
	scanf("%lld%lld", &n, &q);
	sqr = sqrt(n);
	for(int i = 1;i <= n;i++) scanf("%lld", &a[i]), t[i] = a[i];
	m = n;
	sort(t + 1, t + 1 + m);
	m = unique(t + 1, t + 1 + m) - t - 1;
	for(int i = 1;i <= n;i++) a[i] = lower_bound(t + 1, t + 1 + m, a[i]) - t;
	for(int i = 1;i <= q;i++) {
		scanf("%lld%lld", &Q[i].l, &Q[i].r);
		Q[i].id = i;
	}
	sort(Q + 1, Q + 1 + q, cmp);
	for(int i = 1;i <= n;i++) cnt[i] = i / sqr + (i % sqr != 0);
	for(int i = 1;i <= cnt[n];i++) {
		le[i] = (i - 1) * sqr + 1;
		ri[i] = i * sqr;
		ri[i] = min(ri[i], n);
	}
 	int l = 1, r = 0, lt = 0;
	for(int i = 1;i <= q;i++) {
		if(cnt[Q[i].l] == cnt[Q[i].r]) {
			int res = 0;
			for(int j = Q[i].l;j <= Q[i].r;j++) chk[a[j]] ++;
			for(int j = Q[i].l;j <= Q[i].r;j++) res = max(res, t[a[j]] * chk[a[j]]); 
			for(int j = Q[i].l;j <= Q[i].r;j++) chk[a[j]] --;
			ansn[Q[i].id] = res;
			continue;
		}
		if(cnt[Q[i].l] != lt) {
			while(r > ri[cnt[Q[i].l]]) del(r --);
			while(l < ri[cnt[Q[i].l]] + 1) del(l ++);
			ans = 0;
			lt = cnt[Q[i].l];
		}
		while(r < Q[i].r) ans = max(ans, ins(++ r));
		int pq = l, tmp = ans;
		while(l > Q[i].l) tmp = max(tmp, ins(-- l));
		ansn[Q[i].id] = tmp;
		while(l < pq) del(l ++);
	}
	for(int i = 1;i <= q;i++) printf("%lld\n", ansn[i]); 
}

服了, 吐了

2022/2/8 15:29
加载中...