首页 > 其他分享 >蒲公英(分块)

蒲公英(分块)

时间:2023-03-21 14:44:36浏览次数:52  
标签:分块 int Pos mx ++ 蒲公英 id

Acwing249蒲公英

[洛谷]([Violet]蒲公英 - 洛谷)

[Acwing(数据较强)](249. 蒲公英 - AcWing题库)

前言

“好诗意的题目啊......

那就用很诗意的代码写吧”

思路

首先, 这题是给你 \(l, r\) 的限制目的是强制在线,所以莫队啥的不能用。

由于不满足“区间可加性”(已知\([l, r] \cup[r+1,k]\) 的众数,不能得出 \([l, k]\) 的众数), 所以树状数组/线段树就很难维护。

考虑分块,首先离散。 设块的长度为 \(T\) , 则有 \(n / T\) 块, 然后预处理第 \(i\) 到 \(j\) 块的众数以及数的出现次数, 这段时间复杂度 \(O(NT^2)\)。 之后两段暴力维护, \(O(N/T)\)

总的时间复杂度 \(O(NT^2 + MN/T)\)

所以如果 \(T=\sqrt{N}\) 时间复杂度就为 \(O(N\sqrt{N})\) ( \(N,M\) 同阶)

#include <bits/stdc++.h>
#define for_(i,a,b) for (int i = (a); i < (b); i++)
#define rep_(i,a,b) for (int i = (a); i <= (b); i++)
#define _Pos(i, j) (((i)-1)*cnt+(j))
using namespace std;
const int maxn = 4e5 + 10, mod = 1e9 + 7;// mod = 1949777;
const double EPS = 1e-3;
int n, m, t, cnt;
int a[maxn], id[maxn], l[maxn], r[maxn], b[maxn], s[maxn];
void solve() {
}
signed main() {
#ifdef LOCAL
    freopen("w.in", "r", stdin);
    freopen("w.ans", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;

    //
    while (t * t * t < n)
        t++;

    t--; //
    t = n / t; //the lenth of a bar
    //
    rep_(i, 1, n) {
        cin >> a[i];
        b[i] = a[i];
    }
    sort(b + 1, b + 1 + n);
    int len = unique(b + 1, b + 1 + n) - b - 1;
    rep_(i, 1, n) {
        a[i] = lower_bound(b + 1, b + 1 + len, a[i]) - b;
    }

    //
    for (int i = 1; i <= n / t; i++) {
        l[i] = (i - 1) * t + 1;
        r[i] = i * t;
    }

    cnt = n / t;

    if (r[cnt] < n) {
        l[cnt + 1] = r[cnt] + 1;
        r[cnt + 1] = n;
        cnt++;
    }

    for (int i = 1; i <= cnt; i++) {
        for (int j = l[i]; j <= r[i]; j++) {
            id[j] = i;
        }
    }

    vector<vector<int>> v(cnt * cnt + 1, vector<int>(n, 0));

    //
    for (int i = 1; i <= cnt; i++) {
        for (int j = i; j <= cnt; j++) {
            for (int k = l[i]; k <= r[j]; k++) {
                v[_Pos(i, j)][a[k]]++;
            }

            int mx = 0, _S = 0;

            for (int k = 1; k <= n; k++) {
                if (mx < v[_Pos(i, j)][k] || mx == v[_Pos(i, j)][k] && _S > k) {
                    mx = v[_Pos(i, j)][k];
                    _S = k;
                }
            }

            s[_Pos(i, j)] = _S;
        }
    }

    //
    vector<int> N(n + 1, 0);
    int _X = 0;

    for (int i = 1, L, R; i <= m; i++) {
        cin >> L >> R;
        L = (L + _X - 1) % n + 1, R = (R + _X - 1) % n + 1;

        if (L > R)
            swap(L, R);

        int mx = 0, _S = 0;

        if (id[L] == id[R]) {
            for (int j = L; j <= R; j++) {
                N[a[j]]++;

                if (mx < N[a[j]] || mx == N[a[j]] && _S > a[j])
                    mx = N[a[j]], _S = a[j];
            }
        } else {
            // Left
            for (int j = L; id[j] == id[L]; j++) {
                N[a[j]]++;

                if (N[a[j]] == 1) {
                    if (id[L] + 1 < id[R]) {
                        N[a[j]] += v[_Pos(id[L] + 1, id[R] - 1)][a[j]];
                    }
                }

                if (mx < N[a[j]] || mx == N[a[j]] && _S > a[j])
                    mx = N[a[j]], _S = a[j];
            }

            // Right
            for (int j = R; id[j] == id[R]; j--) {
                N[a[j]]++;

                if (N[a[j]] == 1) {
                    if (id[L] + 1 < id[R]) {
                        N[a[j]] += v[_Pos(id[L] + 1, id[R] - 1)][a[j]];
                    }
                }

                if (mx < N[a[j]] || mx == N[a[j]] && _S > a[j])
                    mx = N[a[j]], _S = a[j];
            }

            // Mid
            if (id[L] + 1 < id[R] && N[s[_Pos(id[L] + 1, id[R] - 1)]] == 0) {
                int _O = s[_Pos(id[L] + 1, id[R] - 1)];
                int Tmp = v[_Pos(id[L] + 1, id[R] - 1)][_O];

                if (mx < Tmp || mx == Tmp && _S > _O) {
                    mx = Tmp;
                    _S = _O;
                }
            }
        }

        _X = b[_S];
        cout << _X << endl;

        // clear
        for (int j = L; id[j] == id[L]; j++)
            N[a[j]] = 0;

        for (int j = R; id[j] == id[R]; j--)
            N[a[j]] = 0;
    }

    return 0;
}

标签:分块,int,Pos,mx,++,蒲公英,id
From: https://www.cnblogs.com/Cranew/p/17239956.html

相关文章

  • 如何用C语言对十亿数据排序大体就是用分块法把十亿个随机数据排序?
    分析过程将十亿个数据按照一定的规则分成若干个块,每个块包含M个数据,其中M是一个适当的大小,可以根据实际情况进行调整。1、对每个块内的数据进行排序,可以使用快速排序、归......
  • 突刺贯穿的第二分块
    [CF896E]Welcomehome,Chtholly给定一个长为\(n\)的序列\(a_1\sima_n\),\(m\)次操作,分两种:1lrx,将\(a_l\sima_r\)中\(\gtx\)的数减去\(x\)。2lr......
  • Hate That You Know Me (15黑龙江省赛) (数学公式题)(数论分块) (前缀和,小的数学结论
      思路;遇到数学公式,一层一层剥开发现那个式子就是求n内的每一个数的倍数在n以内的数量,明显数论分块来处理这个问题然后就是因子的^2,^3,这个子问题......
  • 【CF1491H Yuezheng Ling and Dynamic Tree】(分块)
    原题链接题意给定一棵大小为\(n\)的\(1\)为根节点的树,树用如下方式给出:输入\(a_2,a_3,\dots,a_n\),保证\(1\leqa_i<i\),将\(a_i\)与\(i\)连边形成一棵树。接下......
  • uniapp 蒲公英升级
    exportfunctioncheckUpdateApp(){//获取manifest.json里的配置信息plus.runtime.getProperty(plus.runtime.appid,function(widgetinfo){//可......
  • [科技] 分块 FFT
    其实也不是啥科技。就是一些卷积形式的东西,直接FFT复杂度非常大。但是你分块以后再FFT/NTT就很牛逼。CodeChefCOUNTARI按照\(i,j,k\)在哪个块中,分类讨论......
  • 数学结构化语言——矩阵的分块简化(四)
    分块矩阵是线性代数中的一个重要内容,是处理阶数较高的矩阵时常采用的技巧,也是数学在多领域的研究工具。对矩阵进行适当分块,可使高阶矩阵的运算可以转化为低阶矩阵的运算,同......
  • 省选备战报告 第零辑 分块与根号平衡
    本笔记仅仅记录重点思路,详细解题过程请参阅原题题解难度从低到高为NÄIVE:有效思考时间少于十分钟EASY:能够完全独立得出MEDIUMEASY:需要题解提供关键思路跨越MEDIUM:需......
  • Java多线程分块下载器
    '''javaimportjava.io.*;importjava.net.HttpURLConnection;importjava.net.URL;importjava.nio.file.Files;importjava.nio.file.Path;importjava.nio.file.S......
  • 大文件分块上传
    #1.项目背景由于用户需求,需要上传大量图片,只能通过上传压缩包的形式上传,可是压缩包过大时,又会出现上传超时的情况,故需要将压缩包分块上传,然后解压缩图片、若图片过大则再......