AtCoder Beginner Contest 250

E - Prefix Equality

https://atcoder.jp/contests/abc250/tasks/abc250_e

Time Limit: 4 sec / Memory Limit: 1024 MB

Score : 500 points

Problem Statement

You are given integer sequences A=(a1,,aN) and B=(b1,,bN), each of length NN.

For i=1,...,Q, answer the query in the following format.

  • If the set of values contained in the first xi terms of A, (a1,,axi), and the set of values contained in the first yi terms of B, (b1,,byi), are equal, then print Yes; otherwise, print No.

Constraints

  • 1N,Q2×105
  • 1ai,bi109
  • 1xi,yiN
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
a1 aN
b1 bN
Q
x1 y1

xQ yQ

Output

Print Q lines. The i-th line should contain the response to the i-th query.


Sample Input 1

5
1 2 3 4 5
1 2 2 4 3
7
1 1
2 2
2 3
3 3
4 4
4 5
5 5

Sample Output 1

Yes
Yes
Yes
No
No
Yes
No

Note that sets are a concept where it matters only whether each value is contained or not.
For the 3-rd query, the first 2 terms of A contain one 1 and one 2, while the first 3 terms of B contain one 1 and two 2's. However, the sets of values contained in the segments are both {1,2}, which are equal.
Also, for the 66-th query, the values appear in different orders, but they are still equal as sets.

我的笔记

使用 hash 计算出 a1axb1bx(1xN) 所含数字集合的 hash 值,存到长为 N 的数组 hash_ahash_b 内。

判断时,只需判断 hash_a[xi] 是否等于 hash_b[yi]。若等于,则集合相等;不等,则集合不等。

hash 函数可用 f(x)=x(x+1326)(x+9185),使用自然溢出法。

源码

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2e5 + 20;
int N, Q;
unsigned int hash_a[MAXN], hash_b[MAXN];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> N;
    set<int> st;
    for (int i = 0; i < N; i++)
    {
        int tmp;
        cin >> tmp;
        if (st.find(tmp) == st.end())
        {
            st.insert(tmp);
            hash_a[i + 1] = (hash_a[i] + tmp * (tmp + 1326) * (tmp + 9185));
        }
        else
        {
            hash_a[i + 1] = hash_a[i];
        }
    }
    st.clear();
    for (int i = 0; i < N; i++)
    {
        int tmp;
        cin >> tmp;
        if (st.find(tmp) == st.end())
        {
            st.insert(tmp);
            hash_b[i + 1] = (hash_b[i] + tmp * (tmp + 1326) * (tmp + 9185));
        }
        else
        {
            hash_b[i + 1] = hash_b[i];
        }
    }
    cin >> Q;
    while (Q--)
    {
        int a, b;
        cin >> a >> b;
        if (hash_a[a] == hash_b[b])
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
    }
    return 0;
}