zoukankan      html  css  js  c++  java
  • 洛谷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;
    }
    
  • 相关阅读:
    Xcode7中你一定要知道的炸裂调试神技【转载】
    让Category支持添加属性与成员变量【转载】
    KVC与KVO
    时间与日期处理【转载】
    iOS 字符属性NSAttributedString描述【转载】
    搜索引擎-倒排索引基础知识
    sql server命令行
    复习索引
    【藏】使用Entity Framework时要注意的一些性能问题
    windows 8.1 安装 .Net Framework 3.5
  • 原文地址:https://www.cnblogs.com/quanjun/p/15528602.html
Copyright © 2011-2022 走看看