[SOJ475]SPC #2美丽的序列 ~ Beautiful Sequence莫队哈希
Posted suwakow
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SOJ475]SPC #2美丽的序列 ~ Beautiful Sequence莫队哈希相关的知识,希望对你有一定的参考价值。
题意简述:给一个长度为(n)的序列,每次给出(x, y),求有多少区间([l, r])满足(xleq lleq rleq y),且([l, r])中每个元素都出现了偶数次。(1leq n, q leq 10^5, 1leq a_ileq 10^6)。
设(s_{i, j}in[0, 1])表示前(i)个位置中,元素(j)出现的总次数(mod 2)的结果。显然([l, r])中每个元素都出现了偶数次等价于(forall iin [1, max a] s_{l-1, i}=s_{r, i})。因此对每个(s_{i})进行哈希,原问题就变成了区间元素出现个数平方和,也就是一道莫队入门题。
#include <bits/stdc++.h>
#define R register
#define ll long long
#define mp make_pair
#define pll pair<ll, ll>
using namespace std;
const int N = 110000, M = 1100000;
const ll mod[2] = {1e9 + 7, 1e9 + 9}, base[2] = {19260817, 19660813};
int n, q, B, bel[N], a[N], app[M], num, cnt, b[N], times[N];
ll pw[M][2], hs[N][2], sum, ans[N];
struct node {
int x, y, ind;
node (int x = 0, int y = 0, int i = 0) : x(x), y(y), ind(i) {}
inline bool operator < (const node &a) const {
if (bel[x] == bel[a.x])
return (bel[x] & 1) ? y < a.y : y > a.y;
return bel[x] < bel[a.x];
}
}que[N];
map<pll, int> tab;
template <class T> inline void read(T &x) {
x = 0;
char ch = getchar(), w = 0;
while (!isdigit(ch)) w = (ch == '-'), ch = getchar();
while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
x = w ? -x : x;
return;
}
inline void add(int p) {
sum += times[b[p]], ++times[b[p]];
return;
}
inline void del(int p) {
--times[b[p]], sum -= times[b[p]];
return;
}
int main() {
int x, y;
read(n);
int maxA = 0;
for (R int i = 1; i <= n; ++i)
read(a[i]), maxA = max(maxA, a[i]);
pw[0][0] = pw[0][1] = 1;
for (R int i = 1; i <= maxA; ++i)
pw[i][0] = pw[i - 1][0] * base[0] % mod[0], pw[i][1] = pw[i - 1][1] * base[1] % mod[1];
tab[mp(0, 0)] = cnt = 1;
for (R int i = 1; i <= n; ++i) {
if (app[a[i]]) {
hs[i][0] = (hs[i - 1][0] + mod[0] - pw[a[i]][0]) % mod[0];
hs[i][1] = (hs[i - 1][1] + mod[1] - pw[a[i]][1]) % mod[1];
}
else {
hs[i][0] = (hs[i - 1][0] + pw[a[i]][0]) % mod[0];
hs[i][1] = (hs[i - 1][1] + pw[a[i]][1]) % mod[1];
}
app[a[i]] ^= 1;
pll now = mp(hs[i][0], hs[i][1]);
if (tab.find(now) == tab.end())
tab[now] = ++cnt;
b[i] = tab[now];
}
read(q);
B = max(1, (int) (n / sqrt(q)));
for (R int i = 0; i < n; ++i)
bel[i + 1] = i / B + 1;
for (R int i = 1; i <= q; ++i)
read(x), read(y), que[++num] = node(x - 1, y, i);
sort(que + 1, que + 1 + q);
int p1 = 0, p2 = 0;
times[1] = b[0] = 1;
for (R int i = 1; i <= q; ++i) {
while (p2 < que[i].y) add(++p2);
while (p1 > que[i].x) add(--p1);
while (p1 < que[i].x) del(p1++);
while (p2 > que[i].y) del(p2--);
ans[que[i].ind] = sum;
}
for (R int i = 1; i <= q; ++i)
printf("%lld
", ans[i]);
return 0;
}
以上是关于[SOJ475]SPC #2美丽的序列 ~ Beautiful Sequence莫队哈希的主要内容,如果未能解决你的问题,请参考以下文章