萌新刚学莫队求教复杂度
查看原帖
萌新刚学莫队求教复杂度
761491
Zzzcr楼主2023/6/7 22:34

正常思路应该是移动l,r再算答案,我的做法是先移动值域再移动l,r。 TLE on #9 https://www.luogu.com.cn/record/112240091

#include <bits/stdc++.h>
using namespace std;
// #define int long long
#define rep(i, a, b) for (int i = a; i <= b; ++i)
#define drep(i, a, b) for (int i = a; i >= b; --i)
namespace FastIO
{
    const int MAXSIZE = 1 << 20;
    struct Reader
    {
        template <typename T>
        Reader &operator>>(T &x)
        {
            char c = getchar();
            T f = 1;
            while (!isdigit(c))
                c = getchar();
            x = 0;
            while (isdigit(c))
                x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
            x *= f;
            return *this;
        }
        Reader &operator>>(char &c)
        {
            c = getchar();
            while (c == ' ' || c == '\n')
                c = getchar();
            return *this;
        }
        Reader &operator>>(char *str)
        {
            int len = 0;
            char c = getchar();
            while (c == ' ' || c == '\n')
                c = getchar();
            while (c != ' ' && c != '\n' && c != '\r')
                str[len++] = c, c = getchar();
            str[len] = '\0';
            return *this;
        }
        Reader() {}
    } cin;
    const char endl = '\n';
    struct Writer
    {
        template <typename T>
        Writer &operator<<(T x)
        {
            if (x == 0)
            {
                putchar('0');
                return *this;
            }
            static int sta[111];
            int top = 0;
            while (x)
                sta[++top] = x % 10, x /= 10;
            while (top)
                putchar(sta[top--] + '0');
            return *this;
        }
        Writer &operator<<(char c)
        {
            putchar(c);
            return *this;
        }
        Writer &operator<<(char *str)
        {
            int cur = 0;
            while (str[cur])
                putchar(str[cur++]);
            return *this;
        }
        Writer &operator<<(const char *str)
        {
            int cur = 0;
            while (str[cur])
                putchar(str[cur++]);
            return *this;
        }
        Writer() {}
    } cout;
}
#define cin FastIO::cin
#define cout FastIO::cout
#define endl FastIO::endl
#define N 100000
#define S 320
int n, m, e[N + 5], p[N + 5], q[N + 5], bl[N + 5], cnt[N + 5];
int ans1, ans2;
struct ask
{
    int a, b, l, r, id;
} Q[N + 5];
bool cmp(ask x, ask y)
{
    if (bl[x.a] != bl[y.a])
        return x.a < y.a;
    if (bl[x.b] != bl[y.b])
        return x.b < y.b;
    if (bl[x.l] != bl[y.l])
        return x.l < y.l;
    return x.r < y.r;
}
signed main()
{
    cin >> n >> m;
    rep(i, 1, n) cin >> e[i];
    rep(i, 1, N) bl[i] = (i - 1) / S + 1;
    rep(i, 1, m) cin >> Q[i].l >> Q[i].r >> Q[i].a >> Q[i].b, Q[i].id = i;
    sort(Q + 1, Q + m + 1, cmp);
    int L = 1, R = 0, A = 1, B = 0;
    rep(i, 1, m)
    {
        int l = Q[i].l, r = Q[i].r, a = Q[i].a, b = Q[i].b, id = Q[i].id;
        while (a < A)
        {
            ans1 += cnt[--A];
            ans2 += !!cnt[A];
        }
        while (a > A)
        {
            ans1 -= cnt[A];
            ans2 -= !!cnt[A++];
        }
        while (b > B)
        {
            ans1 += cnt[++B];
            ans2 += !!cnt[B];
        }
        while (b < B)
        {
            ans1 -= cnt[B];
            ans2 -= !!cnt[B--];
        }
        while (l < L)
        {
            if (e[--L] >= a && e[L] <= b)
            {
                if (cnt[e[L]] == 0)
                    ans2++;
                ans1++;
            }
            cnt[e[L]]++;
        }
        while (l > L)
        {
            if (e[L] >= a && e[L] <= b)
            {
                if (cnt[e[L]] == 1)
                    ans2--;
                ans1--;
            }
            cnt[e[L++]]--;
        }
        while (r >= R)
        {
            if (e[++R] >= a && e[R] <= b)
            {
                if (cnt[e[R]] == 0)
                    ans2++;
                ans1++;
            }
            cnt[e[R]]++;
        }
        while (r < R)
        {
            // R--;
            if (e[R] >= a && e[R] <= b)
            {
                if (cnt[e[R]] == 1)
                    ans2--;
                ans1--;
            }
            cnt[e[R--]]--;
        }
        p[id] = ans1, q[id] = ans2;
    }
    rep(i, 1, m) cout << p[i] << ' ' << q[i] << '\n';
    return 0;
}

2023/6/7 22:34
加载中...