萌新刚学OI求助,分块全WA
查看原帖
萌新刚学OI求助,分块全WA
253433
XeRnHe楼主2021/11/13 20:06

刚写分块,调了好久心态爆炸了。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>

using namespace std;

typedef long long ll;
const ll MAXN = 40005;
const ll MAXB = 205;

ll n, m, w;
ll a[MAXN], b[MAXN];

namespace Operator {
    inline void Swap(ll &x, ll &y) {
        ll t = x; x = y; y = t;
    }
} using namespace Operator;

namespace Blocks {
    ll tot, len;
    ll belong[MAXN], posL[MAXN], posR[MAXN];
    ll t[MAXN], dict[MAXB][MAXN], mode[MAXB][MAXB];

    void buildBlock() {
        len = sqrt(n);
        tot = n / len;
        for (ll i = 1; i <= n; i++) {
            belong[i] = (i - 1) / len + 1;
        }
        for (ll i = 1; i <= tot; i++) {
            posL[i] = posR[i - 1] + 1;
            posR[i] = i * len;
        }
        if (posR[tot] < n) {
            tot++;
            posL[tot] = posR[tot - 1] + 1;
            posR[tot] = n;
        }
        for (ll i = 1; i <= tot; i++) {
            for (ll j = 1; j <= w; j++) {
                dict[i][j] = dict[i - 1][j];
            }
            for (ll j = posL[i]; j <= posR[i]; j++) {
                dict[i][a[j]]++;
            }
        }
        for (ll i = 1; i <= tot; i++) {
            memset(t, 0, sizeof(t));
            for (ll j = i; j <= tot; j++) {
                mode[i][j] = mode[i][j - 1];
                for (ll k = posL[j]; k <= posR[j]; k++) {
                    t[a[k]]++;
                    if ((t[a[k]] > t[mode[i][j]]) || (t[a[k]] == t[mode[i][j]] && a[k] < mode[i][j])) {
                        mode[i][j] = a[k];
                    }
                }
            }
        }
        memset(t, 0, sizeof(t));
    }

    ll query(ll l, ll r) {
        ll result = 0;
        if (belong[l] == belong[r]) {
            for (ll i = l; i <= r; i++) {
                t[a[i]]++;
                if ((t[a[i]] > t[result]) || (t[a[i]] == t[result] && a[i] < result)) {
                    result = a[i];
                }
            }
        } else {
            for (ll i = l; i <= posR[belong[l]]; i++) {
                t[a[i]]++;
            }
            for (ll i = posL[belong[r]]; i <= r; i++) {
                t[a[i]]++;
            }
            result = mode[belong[l] + 1][belong[r] - 1];
            for (ll i = l; i <= posR[belong[l]]; i++) {
                ll nowAns = t[a[i]] + dict[belong[r] - 1][a[i]] - dict[belong[l]][a[i]];
                ll oldAns = t[result] + dict[belong[r] - 1][result] - dict[belong[l]][result];
                if (nowAns > oldAns || (nowAns == oldAns && a[i] < result)) {
                    result = a[i];
                }
            }
            for (ll i = posL[belong[r]]; i <= r; i++) {
                ll nowAns = t[a[i]] + dict[belong[r] - 1][a[i]] - dict[belong[l]][a[i]];
                ll oldAns = t[result] + dict[belong[r] - 1][result] - dict[belong[l]][result];
                if (nowAns > oldAns || (nowAns == oldAns && a[i] < result)) {
                    result = a[i];
                }
            }
        }
        result = b[result];
        return result;
    }
} using namespace Blocks;

int main() {
    cin >> n >> m;
    for (ll i = 1; i <= n; i++) {
        cin >> a[i];
        b[i] = a[i];
    }
    sort(b + 1, b + n + 1);
    w = unique(b + 1, b + n + 1) - b - 1;
    for (ll i = 1; i <= n; i++) {
        a[i] = lower_bound(b + 1, b + w + 1, a[i]) - b;
    }
    buildBlock();
    ll lastans = 0;
    while (m--) {
        ll l, r;
        cin >> l >> r;
        l = (l + lastans - 1) % n + 1;
        r = (r + lastans - 1) % n + 1;
        if (l > r) {
            Swap(l, r);
        }
        ll lastans = query(l, r);
        cout << lastans << endl;
    }
    return 0;
}
2021/11/13 20:06
加载中...