[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莫队哈希的主要内容,如果未能解决你的问题,请参考以下文章

[SOJ]连通性问题

P2659 美丽的序列

P2659 美丽的序列

洛谷P2659美丽的序列

Codeforces Round #475 (Div. 2) D. Destruction of a Tree

Codeforces475D - CGCDSSQ