60pts求助

P2801 教主的魔法

syr1125 @ 2024-06-01 10:49:30

我又又又来求助了

#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 5, sN = 1e3 + 5;
int n, q, a[N], id[N], L[sN], R[sN], lazy[sN], vis[sN];

int main()
{
    scanf("%d %d", &n, &q);
    int sn = sqrt(n);
    for (int i = 1; i <= n; i ++)
    {
        scanf("%d", &a[i]);
        id[i] = i / sn + (bool)(i % sn);
    }
    for (int i = 1; i <= n + 1; i ++)
    {
        if (id[i] != id[i - 1]) L[id[i]] = i;
        if (id[i] != id[i + 1]) R[id[i]] = i;
    }

    while (q --)
    {
        char op;
        int l, r, w;
        cin >> op >> l >> r >> w;
        if (op == 'M')
        {
            int sid = id[l], eid = id[r];
            vis[sid] = 0, vis[eid] = 0;
            if (sid == eid)
            {
                for (int i = l; i <= r; i ++) a[i] += w;
            }
            for (int i = l; i <= R[sid]; i ++) a[i] += w;
            for (int i = sid + 1; i <= eid - 1; i ++) lazy[i] += w;
            for (int i = L[eid]; i <= r; i ++) a[i] += w;
        }
        else
        {
            int sid = id[l], eid = id[r], ans = 0;
            if (sid == eid)
            {
                for (int i = l; i <= r; i ++)
                {
                    if (a[i] + lazy[sid] >= w) ans ++;  
                }
            }
            for (int i = l; i <= R[sid]; i ++)
            {
                if (a[i] + lazy[sid] >= w) ans ++;
            }
            for (int i = sid + 1; i <= eid - 1; i ++)
            {
                if (!vis[i]) sort(a + L[i], a + R[i] + 1);
                ans += (R[i] - L[i] + 1) - (lower_bound(a + L[i], a + R[i] + 1, w - lazy[i]) - (a + L[i]));
            }
            for (int i = L[eid]; i <= r; i ++)
            {
                if (a[i] + lazy[eid] >= w) ans ++;
            }
            cout << ans << "\n";
        }
    }
    return 0;
}

感觉分块假了,分块分成了暴力


by syr1125 @ 2024-06-01 11:00:27

已AC,这边是优化假了


|