歴史の研究回滚莫队wa#46求调
查看原帖
歴史の研究回滚莫队wa#46求调
947565
_ERO_楼主2023/4/4 22:10

wa在了第46个点,拍不出数据

评测记录

#include<cstdio>
#include<cctype>
#include<cmath>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;

const int MAXN = 100005;

inline int read() {
		int x = 0; char c = getchar();
		while (!isdigit(c)) c = getchar();
		while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
		return x;
}
inline void write(int x) {
		if (x > 9) write(x / 10);
		putchar (x % 10 + 48);
}

int n, m, a[MAXN], num[MAXN], inp[MAXN], ans[MAXN], tcnt[MAXN];
int belong[MAXN], lb[MAXN], rb[MAXN], cnt[MAXN], now, siz, bnum;
//a, inp离散化,num存原值,tcnt见主函数
//belong所在块,lb rb分别指块i的左、右端点,cnt计数,now目前值,siz块长,bnum块数量 

struct Query {//离线询问 
		int l, r, id;
}q[MAXN];
inline bool cmp(Query a, Query b) {//以左端点所在块为第一关键字,右端点位置为第二 
		return (belong[a.l] ^ belong[b.l]) ? belong[a.l] < belong[b.l] : a.r < b.r;
}

inline void add(int p) {//添加 
		++ cnt[a[p]];
		now = max(now, cnt[a[p]] * num[p]);
}

signed main()
{
		n = read(), m = read();
		//离散化 num表示i位置的初始值 
		for (int i = 1; i <= n; ++ i) inp[i] = num[i] = a[i] = read();
		sort (inp + 1, inp + n + 1); int len = unique(inp + 1, inp + n + 1) - inp - 1;
		for (int i = 1; i <= n; ++ i) a[i] = lower_bound(inp + 1, inp + len + 1, a[i]) - inp;
		
		siz = sqrt(n); bnum = ceil(double(n) / siz);//分块 
		for (int i = 1; i <= bnum; ++ i) {
				lb[i] = siz * (i - 1) + 1;
				rb[i] = siz * i;
				for (int j = lb[i]; j <= rb[i]; ++ j) belong[j] = i;
		}
		
		for (int i = 1; i <= m; ++ i) q[i].l = read(), q[i].r = read(), q[i].id = i;
		sort (q + 1, q + m + 1, cmp);//排序 
		
		for (int i = 1, lst = 0, l , r; i <= m; ++ i) {//lst存上一个块编号+1 
				int ql = q[i].l, qr = q[i].r;
				
				if (belong[ql] == belong[qr]) {//如果在同一个块不需要滚 
						now = 0;
						for (int j = ql; j <= qr; ++ j) ++ tcnt[a[j]], now = max(now, tcnt[a[j]] * num[j]);
						ans[q[i].id] = now;
						for (int j = ql; j <= qr; ++ j) -- tcnt[a[j]];
						continue;
				}
				
				if (belong[ql] + 1 != lst) {//不是同一个块了 
						lst = belong[ql] + 1; now = 0;
						memset(cnt, 0, sizeof(cnt));
						l = lb[lst], r = rb[lst - 1];
				}
				
				while (r < qr) add(++ r);//更新右端点 
				
				int tmp = now;//回滚 
				while (l > ql) add(-- l); ans[q[i].id] = now;
				while (l < lb[lst] + 1) -- cnt[a[l ++]]; now = tmp;
		}
		
		for (int i = 1; i <= m; ++ i) write(ans[i]), putchar('\n');
		
		return 0;
}
2023/4/4 22:10
加载中...