Hướng dẫn giải của Bedao Regular Contest 19 - SetQuery


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Ta có thể sử dụng hash cộng hoặc hash xor, vấn đề của bài này là với mỗi đoạn ta chỉ hash đúng một lần các giá trị xuất hiện. Ban đầu ta gán lại các giá trị với một số random nào đó để khó bị trùng lặp.

Ta sẽ xử lí offline cho từng đoạn xuất hiện trong truy vấn, việc chỉ lấy giá trị xuất hiện ~1~ lần khá giống với bài DQuery.

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5+5;
int n,q;
int a[N],b[N];
int HashA[N],HashB[N];
vector<int> event[N];
mt19937 ran(time(0));
int Rand(int l, int r) {
    return l + ran()%(r-l+1);
}
map<int,int> mp;
struct Query {
    int l,r,id;
}queryA[N],queryB[N];
int ansA[N],ansB[N];
struct fenwick {
    int n; 
    vector<int> bit;
    fenwick(){}
    fenwick(int n) :n(n) {
        bit.assign(n+5,0);
    }
    void update (int u, int val) {
        for (u; u<=n; u += u & (-u)) bit[u] ^= val;
    }  
    int get (int u) {
        int res = 0;
        for (u; u>0; u -= u & (-u)) res ^= bit[u];
        return res;
    }
    int get (int l, int r) {
        return get(r) ^ get(l-1);
    }
}tree;
void solve (int *a, Query *query, int *ans) {
    map<int,int> pos;
    tree = fenwick(n);
    for (int i=1; i<=n; i++) {
        event[i].clear();
    }
    for (int i=1; i<=q; i++) {
        event[query[i].r].push_back(i);
    }
    for (int i=1; i<=n; i++) {
        if (pos.count(a[i])) {
            tree.update(pos[a[i]],a[i]);
        }
        pos[a[i]] = i;
        tree.update(pos[a[i]],a[i]);
        for (auto u : event[i]) ans[query[u].id] = tree.get(query[u].l,i);
    }
}
signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> q;
    for (int i=1; i<=n; i++) {
        cin >> a[i];
        if (mp.count(a[i]) == 0) mp[a[i]] = Rand(1,1e18);
        a[i] = mp[a[i]];
    } 
    for (int i=1; i<=n; i++) {
        cin >> b[i];
        if (mp.count(b[i]) == 0) mp[b[i]] = Rand(1,1e18);
        b[i] = mp[b[i]];
    }
    for (int i=1; i<=q; i++) {
        cin >> queryA[i].l >> queryA[i].r >> queryB[i].l >> queryB[i].r;
        queryA[i].id= queryB[i].id = i;
    }
    solve(a,queryA,ansA);
    solve(b,queryB,ansB);
    for (int i=1; i<=q; i++) {
        if (ansA[i] == ansB[i]) cout << "YES\n";
        else cout << "NO\n";
    }
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.