• 洛谷P4168 [Violet]蒲公英 题解 数列分块


    题目大意:对大小为 \(n\) 的数列进行 \(m\) ,每次求出区间最小众数。

    解题思路:数列分块。同:LOJ6285. 数列分块入门 9

    示例程序:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 40040;
    
    int n, m, blo, id, a[maxn], bl[maxn], p[202][202];
    map<int, int> mp;
    int val[maxn], cnt[maxn];
    vector<int> g[maxn];
    
    void pre(int x) {
        memset(cnt, 0, sizeof(cnt));
        int res = 0, mx = 0;
        for (int i = (x-1)*blo+1; i <= n; i ++) {
            cnt[a[i]] ++;
            int t = bl[i];
            if (cnt[a[i]] > mx || cnt[a[i]] == mx && val[a[i]] < val[res]) {
                res = a[i];
                mx = cnt[a[i]];
            }
            p[x][t] = res;
        }
    }
    
    int mycount(int l, int r, int x) {
        return upper_bound(g[x].begin(), g[x].end(), r) - lower_bound(g[x].begin(), g[x].end(), l);
    }
    
    int query(int l, int r) {
        int res = p[bl[l]+1][bl[r]-1], mx = mycount(l, r, res);
        for (int i = l; i <= min(bl[l]*blo, r); i ++) {
            int t = mycount(l, r, a[i]);
            if (t > mx || t == mx && val[a[i]] < val[res]) {
                res = a[i];
                mx = t;
            }
        }
        if (bl[l] != bl[r]) {
            for (int i = (bl[r]-1)*blo+1; i <= r; i ++) {
                int t = mycount(l, r, a[i]);
                if (t > mx || t == mx && val[a[i]] < val[res]) {
                    res = a[i];
                    mx = t;
                }
            }
        }
        return res;
    }
    
    int main() {
        ios::sync_with_stdio(0);
        cin >> n >> m;
        blo = sqrt(n);
        for (int i = 1; i <= n; i ++) {
            cin >> a[i];
            bl[i] = (i - 1) / blo + 1;
            if (!mp[a[i]]) {
                mp[a[i]] = ++id;
                val[id] = a[i];
            }
            a[i] = mp[a[i]];
            g[a[i]].push_back(i);
        }
        for (int i = 1; i <= bl[n]; i ++)
            pre(i);
        int l, r, x = 0;
        for (int i = 1; i <= m; i ++) {
            int l0, r0;
            cin >> l0 >> r0;
            l = (l0 + x -1) % n + 1;
            r = (r0 + x - 1) % n + 1;
            if (l > r) swap(l, r);
            x = val[query(l, r)];
            cout << x << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    FEniCS 1.1.0 发布,计算算术模型
    Piwik 1.10 发布,增加社交网站统计
    淘宝褚霸谈做技术的心态
    CyanogenMod 10.1 M1 发布
    Druid 发布 0.2.11 版本,数据库连接池
    GNU Gatekeeper 3.2 发布
    Phalcon 0.9.0 BETA版本发布,新增大量功能
    EUGene 2.6.1 发布,UML 模型操作工具
    CVSps 3.10 发布,CVS 资料库更改收集
    Opera 移动版将采用 WebKit 引擎
  • 原文地址:https://www.cnblogs.com/quanjun/p/15528602.html
Copyright © 2020-2023  润新知