萌新刚学分块,分块90pts求调 WA on #1

P2801 教主的魔法

喵仔牛奶 @ 2022-07-27 19:25:37

rt,萌新写了一个丑陋的 m\sqrt n\log n 分块,结果WA了,求调。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
int pos[N], L[N], R[N], n, q, l, r, cnt, slen;
ll a[N], sorted[N], tag[N], x;
char opt;
void build() {
    slen = sqrt(n), cnt = n / slen + (n % slen != 0);
    for (int i = 1; i <= cnt; i ++)
        L[i] = (i - 1) * slen + 1, R[i] = i * slen;
    R[cnt] = n;
    for (int i = 1; i <= cnt; i ++) {
        for (int j = L[i]; j <= R[i]; j ++)
            pos[j] = i, sorted[j] = a[j];
        sort(sorted + L[i], sorted + R[i] + 1);
    }
}
int bound(int l, int r, ll x) {
    int ans = l;
    while (l <= r) {
        int mid = (l + r) / 2;
        if (sorted[mid] >= x) ans = mid, r = mid - 1;
        else l = mid + 1;
    }
    return ans;
}
int find(int l, int r, ll x) {
    int lp = pos[l], rp = pos[r], ans = 0;
    if (lp == rp) {
        for (int i = l; i <= r; i ++)
            if (a[i] + tag[lp] >= x) ans ++;
        return ans;
    }
    for (int i = lp + 1; i < rp; i ++) {
        ans += R[i] - bound(L[i], R[i], x - tag[i]) + 1;
    }
    for (int i = l; i <= R[lp]; i ++) ans += ((a[i] + tag[lp]) >= x);
    for (int i = L[rp]; i <= r; i ++) ans += ((a[i] + tag[rp]) >= x);
    return ans;
}
void change(int l, int r, ll x) {
    int lp = pos[l], rp = pos[r];
    if (lp == rp) {
        for (int i = l; i <= r; i ++)
            a[i] += x;
        for (int i = L[lp]; i <= R[lp]; i ++)
            sorted[i] = a[i];
        sort(sorted + L[lp], sorted + R[lp] + 1);
        return;
    }
    for (int i = l; i <= R[lp]; i ++)
        a[i] += x;
    for (int i = L[lp]; i <= R[lp]; i ++)
        sorted[i] = a[i];
    sort(sorted + L[lp], sorted + R[lp] + 1);
    for (int i = lp + 1; i < rp; i ++)
        tag[i] += x;    
    for (int i = L[rp]; i <= r; i ++)
        a[i] += x;
    for (int i = L[rp]; i <= R[rp]; i ++)
        sorted[i] = a[i];
    sort(sorted + L[rp], sorted + R[rp] + 1); 
}
int main() {
    cin >> n >> q;
    for (int i = 1; i <= n; i ++)
        cin >> a[i];
    build();
    for (int i = 1; i <= q; i ++) {
        cin >> opt >> l >> r >> x;
        if (opt == 'M') change(l, r, x);
        else cout << find(l, r, x) << '\n';
    }
    return 0;
}

by 喵仔牛奶 @ 2022-07-27 19:26:32

此贴完结,SB楼主二分写挂了。


by THZH @ 2023-08-16 16:07:52

作弊者。。。


|