• Loj 6285. 数列分块入门 9


    链接:

    https://loj.ac/problem/6285

    思路:

    离散化处理下就好了,具体解释在代码里、

    ps:

    小新新别看了,你学不会的

    实现代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int M = 1e5 + 10;
    int n,block,idx,a[M],bl[M],f[510][510],val[M],cnt[M];
    vector<int>ve[M];
    void pre(int x){  //预处理
        memset(cnt,0,sizeof(cnt));
        int mx = 0, ans = 0;
        for(int i = (x - 1)*block+1;i <= n;i ++){
            cnt[a[i]]++;
            int t = bl[i];
            if(cnt[a[i]] > mx||(cnt[a[i]]==mx&&val[a[i]]<val[ans])) //如果在当前区间出现次数比最大值或者和最大值一样但是值比最大值小,那么更新最大值
                ans = a[i],mx = cnt[a[i]];
            f[x][t] = ans;  //代表 x块 到 t块中的最小众数
        }
    }
    
    int query(int l,int r,int x){  //在ve[ai]二分寻找在l,r区间的a[i]的数量
        int t = upper_bound(ve[x].begin(),ve[x].end(),r) - lower_bound(ve[x].begin(),ve[x].end(),l);
        return t;
    }
    
    int query(int l,int r){
        int ans,mx;
        ans = f[bl[l]+1][bl[r]-1]; //完整块的查询
        mx = query(l,r,ans);
        //非完整块的查询
        for(int i = l;i <= min(bl[l]*block,r);i ++){
            int t = query(l,r,a[i]);
            if(t > mx||(t == mx&&val[a[i]] < val[ans]))
                ans = a[i],mx = t;
        }
        if(bl[l] != bl[r]){
            for(int i = (bl[r]-1)*block+1;i <= r;i ++){
                int t = query(l,r,a[i]);
                if(t > mx||(t == mx&&val[a[i]] < val[ans]))
                    ans = a[i],mx = t;
            }
        }
        return ans;
    }
    map<int,int>mp;
    int main()
    {
        int l,r;
        scanf("%d",&n);
        block = sqrt(n);
        for(int i = 1;i <= n;i ++){
            scanf("%d",&a[i]);
            if(!mp[a[i]]){
                mp[a[i]] = ++idx;   //离散化
                val[idx] = a[i];    //val数组储存离散化之前的值
            }
            a[i] = mp[a[i]]; //离散化
            ve[a[i]].push_back(i);  //将每个a[i]出现的下标存到a[i]对应的vecotr里
        }
        for(int i = 1;i <= n;i ++) bl[i] = (i - 1)/block + 1;
        for(int i = 1;i <= bl[n];i ++)  pre(i); //预处理每一个块
        for(int i = 1;i <= n;i ++) {
            scanf("%d%d",&l,&r);
            if(l > r) swap(l,r);
            printf("%d
    ",val[query(l,r)]);
        }
        return 0;
    }
  • 相关阅读:
    [LeetCode] 806. Number of Lines To Write String
    [LeetCode] 728. Self Dividing Numbers
    [LeetCode] 852. Peak Index in a Mountain Array
    [LeetCode] 617. Merge Two Binary Trees
    [LeetCode] 876. Middle of the Linked List
    [LeetCode] 461. Hamming Distance
    不会装电脑?手把手教你装电脑,详细到螺丝!
    零基础到精通Web渗透测试的学习路线
    EXE转JPG后缀格式工具(真实JPG后缀)
    知名渗透测试利器分享
  • 原文地址:https://www.cnblogs.com/kls123/p/9379256.html
Copyright © 2020-2023  润新知