站外题求卡常
  • 板块学术版
  • 楼主喵仔牛奶
  • 当前回复11
  • 已保存回复11
  • 发布时间2022/8/4 18:34
  • 上次更新2023/10/27 17:01:24
查看原帖
站外题求卡常
560516
喵仔牛奶楼主2022/8/4 18:34

给定两个长度为 NN 的序列 AABB,现在有 QQ 个询问,每个询问给出两个数字 XXYY, 你需要回答 AA 序列前 XX 个元素构成的集合跟 BB 序列前 YY 个元素构成的集合是否相同,相同输出 Yes, 否则输出 No,每个询问占一行。(集合指去重后的元素集合即 <set>)

1N,Q2×1051\leq N,Q\leq2\times10^5

模拟赛题,赛时我写了莫队,忘记离散化炸了,赛后写了正解,可是莫队死活过不去,时间复杂度 O(nm)O(n\sqrt m) 正确的。

#pragma GCC optimize("Ofast")
#pragma GCC optimize(1, 2, 3, "inline")
#include <unordered_map>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <set>
using namespace std;
typedef long long ll;
const int N = 4e5 + 5;
struct opt {
	int l, r, id;
} s[N];
ll a[N], c[N], ans[N], pos[N], cnt1[N], cnt2[N], t[N], slen, sum, cnt, siz, n, m, l, r;
bool w[N];
inline bool cmp(opt x, opt y) {
	if (pos[x.l] != pos[y.l]) return x.l < y.l;
	return (pos[x.l] & 1) ? x.r < y.r : x.r > y.r;
}
inline void push(int x) {
	if (!w[x]) w[x] = true, siz ++;
	else w[x] = false, siz --;
}
inline int read() {
	register int t = 1, a = 0;
	register char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-') t = -1;
		ch = getchar();
	}
	while (ch <= '9' && ch >= '0')
		a = a * 10 + ch - '0', ch = getchar();
	return a * t;
}
inline void write(long long x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
void init() {
	n = read(), slen = n / sqrt(n);
	for (int i = 1; i <= n; i ++)
		a[i] = read(), t[++ cnt] = a[i];
	for (int i = 1; i <= n; i ++)
		c[i] = read(), t[++ cnt] = c[i];
	m = read();
	for (int i = 1; i <= n; i ++)
		pos[i] = (i - 1) / slen + 1;
	sort(t + 1, t + 1 + cnt);
	sum = unique(t + 1, t + 1 + cnt) - t - 1;
	for (int i = 1; i <= n; i ++)
		a[i] = lower_bound(t + 1, t + 1 + sum, a[i]) - t;
	for (int i = 1; i <= n; i ++)
		c[i] = lower_bound(t + 1, t + 1 + sum, c[i]) - t;
}
int main() {
	init();
	for (int i = 1; i <= m; i ++)
		s[i].l = read(), s[i].r = read(), s[i].id = i;
	sort(s + 1, s + 1 + m, cmp);
	for (int i = 1; i <= m; i ++) {
		while (l > s[i].l) if (!(-- cnt1[a[l --]])) push(a[l + 1]);
		while (l < s[i].l) if (!(cnt1[a[++ l]] ++)) push(a[l]);
		while (r > s[i].r) if (!(-- cnt2[c[r --]])) push(c[r + 1]);
		while (r < s[i].r) if (!(cnt2[c[++ r]] ++)) push(c[r]);
		ans[s[i].id] = !siz;
	}
	for (int i = 1; i <= m; i ++)
		puts(ans[i] ? "Yes" : "No");
	return 0;
}
2022/8/4 18:34
加载中...