喵仔牛奶 @ 2022-08-04 18:34:45
给定两个长度为
N 的序列A 、B ,现在有Q 个询问,每个询问给出两个数字X 、Y , 你需要回答A 序列前X 个元素构成的集合跟B 序列前Y 个元素构成的集合是否相同,相同输出Yes, 否则输出No,每个询问占一行。(集合指去重后的元素集合即<set>)
模拟赛题,赛时我写了莫队,忘记离散化炸了,赛后写了正解,可是莫队死活过不去,时间复杂度
#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;
}
by A_zjzj @ 2022-08-04 18:39:56
貌似可以用哈希做到nlogn?
by 喵仔牛奶 @ 2022-08-04 18:40:54
@A_zjzj 对啊,正解我知道,我已经A了,我就是想让莫队过qwq
by 红黑树 @ 2022-08-04 18:42:33
你现在几秒?时限几秒?
by 王熙文 @ 2022-08-04 18:44:14
at 原题 某次 abc 的 e
by 喵仔牛奶 @ 2022-08-04 18:44:32
@红黑树 时限1s,现在有两个点1100ms以上,剩下的在200ms以下。
老师没有讲过莫队,应该不会故意卡莫队。
by 喵仔牛奶 @ 2022-08-04 18:48:50
@王熙文 有题号吗qwq
by TLEWA @ 2022-08-04 22:22:36
@喵仔牛奶 循环展开+手动O3(如果可以的话)
by TLEWA @ 2022-08-04 22:24:24
@喵仔牛奶 bool数组改bitset(不开O2情况下就算了,不开O2时这玩意还跑不过bool数组)
by TLEWA @ 2022-08-04 22:26:25
az,开了O2啊,火车头走起~
by TLEWA @ 2022-08-04 22:28:43
@喵仔牛奶 火车头
然后自己调,有时全加是负优化...