关于此题[ABC367F] Rearrange Query随机化哈希的一些总结

传送门
这道题要求我们对于非常多的询问回答[l,r]、[L,R]这样两个区间内A、B数组中各个数的出现次数是否相同。
看到这道题似乎想到了刚开始学编程的时候就想过的一个问题(bushi,那就是我能不能直接用,例如说这段区间和是否相同,或者说这段区间乘积之类的是否相同来判断这个区间各个数出现次数是否相同。这道题就给了我答案,那就是利用随机化哈希,即,我们对每一个出现在A、B数组中的数都将它变成一个对应的随机的数,然后对于每个询问的区间来看各自的区间和是否相同即可。注意第一次看到这种做法可能觉得非常荒谬,因为它让人觉得跟我们直接求前缀和来判断相等没有什么两样。这其实就是随机化算法的特点,当这个算法正确率已经达到99.9%甚至往上,我们就可以认定这个做法是正确的。这道题正是如此,我们在232之内随机105量级个数出现两个区间和相同的概率是极小的,而题目给的A、B数组都是关于N的一个排列,这样出现两个区间和相同的概率是很大的。
代码如下:

#include<bits/stdc++.h>

using namespace std;

long long t;
const long long mod = 1e9 + 7;
const long long N = 2e5 + 10;
long long n,qq;
long long a[N],b[N];
long long s1[N],s2[N];
map<long long,long long> q;

void solve() {
    mt19937 myrand(time(nullptr));
    cin >> n >> qq;
    for(long long i = 1;i <= n;i++) {
        cin >> a[i];
        if(!q[a[i]]) q[a[i]] = myrand() % mod;
        a[i] = q[a[i]];
        s1[i] = s1[i-1] + a[i];
    }
    for(long long i = 1;i <= n;i++) {
        cin >> b[i];
        if(!q[b[i]]) q[b[i]] = myrand() % mod;
        b[i] = q[b[i]];
        s2[i] = s2[i-1] + b[i];
    }
    for(long long i = 1;i <= qq;i++) {
        long long l,r,ll,rr;
        cin >> l >> r >> ll >> rr;
        if(s1[r] - s1[l-1] == s2[rr] - s2[ll-1]) cout << "Yes\n";
        else cout << "No\n";
    }
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    t = 1;
    while(t--) solve();

    return 0;
}
posted @   孤枕  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示
相见争如不见,多情何似无情。