• Prefix Equality(哈希)


    题意

    给定两个长度为\(N\)的序列\(A = (a_1, a_2, \dots, a_n)\)\(B = (b_1, b_2, \dots, b_n)\)

    现在有\(Q\)次询问,每次询问给定两个正整数\(x_i\)\(y_i\),问:
    \((a_1, a_2, \dots, a_{x_i})\)构成的集合和\((b_1, b_2, \dots, b_{y_i})\)构成的集合是否相等。

    数据范围

    \(1 \leq N, Q \leq 2 \times 10^5\)

    思路

    考虑哈希。

    对于每一个数,都将其映射到一个随机数。对于一个集合,将这个集合中所有元素的哈希值之和作为整个集合的哈希值。

    如果两个集合的哈希值相等,那么这两个集合相等。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <random>
    #include <map>
    #include <set>
    
    using namespace std;
    
    typedef unsigned long long ull;
    
    const int N = 200010;
    
    mt19937_64 mrand(random_device{}());
    
    int n, q;
    map<int, ull> cnt;
    ull ha[N], hb[N];
    set<int> cnta, cntb;
    
    int main()
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; i ++) {
            int x;
            scanf("%d", &x);
            if(!cnt.count(x)) cnt[x] = mrand();
            ha[i] = ha[i - 1];
            if(!cnta.count(x)) ha[i] += cnt[x];
            cnta.insert(x);
        }
        for(int i = 1; i <= n; i ++) {
            int x;
            scanf("%d", &x);
            if(!cnt.count(x)) cnt[x] = mrand();
            hb[i] = hb[i - 1];
            if(!cntb.count(x)) hb[i] += cnt[x];
            cntb.insert(x);
        }
        scanf("%d", &q);
        while(q --) {
            int x, y;
            scanf("%d%d", &x, &y);
            if(ha[x] == hb[y]) puts("Yes");
            else puts("No");
        }
        return 0;
    }
    
  • 相关阅读:
    const 深悟理解
    深拷贝与浅拷贝深究
    结队开发-最大子数组
    软件工程个人作业02
    四则运算关于加括号的思路
    实践出真知-所谓"java没有指针",那叫做引用!
    写代码的好习惯—先构思
    团队合作
    阿超超的四则运算 想啊想啊
    Github+阿超运算
  • 原文地址:https://www.cnblogs.com/miraclepbc/p/16265144.html
Copyright © 2020-2023  润新知