分块TLE 70pts求助,悬关

P2801 教主的魔法

_x_y_2024 @ 2023-08-17 12:48:09


#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 1e6 + 10;
int n, q, a[N], b[N];
int t, l[N], r[N], pos[N], dat[N];
void reset(int x){
    for(int i = l[x]; i <= r[x]; i++)
        b[i] = a[i];
    sort(b + l[x], b + r[x] + 1);
}
void add(int ll, int rr, int w){
    if(pos[ll] == pos[rr]){
        for(int i = ll; i <= rr; i++)
            a[i] += w;
        return;
    }
    for(int i = ll; i <= r[pos[ll]]; i++)
        a[i] += w;
    reset(pos[ll]);
    for(int i = l[pos[rr]]; i <= rr; i++)
        a[i] += w;
    reset(pos[rr]);
    for(int i = pos[ll] + 1; i <= pos[rr] - 1; i++)
        dat[i] += w;
}
int ask(int ll, int rr, int c){
    if(pos[ll] == pos[rr]){
        int cnt = 0;
        for(int i = ll; i <= rr; i++)
            if(a[i] + dat[pos[ll]] >= c)
                cnt++;
        return cnt;
    }
    int cnt = 0;
    for(int i = ll; i <= r[pos[ll]]; i++)
        if(a[i] + dat[pos[ll]] >= c)
            cnt++;
    for(int i = l[pos[rr]]; i <= rr; i++)
        if(a[i] + dat[pos[rr]] >= c)
            cnt++;
    for(int i = pos[ll] + 1; i <= pos[rr] - 1; i++)
        cnt += r[i] - (lower_bound(b + l[i], b + r[i] + 1, c - dat[i]) - b) + 1;
    return cnt;
}
int main(){
    scanf("%d%d", &n, &q);
    for(int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
        b[i] = a[i];
    }
    t = sqrt(n);
    for(int i = 1; i <= t; i++){
        l[i] = (i-1) * t + 1;
        r[i] = i * t;
    }
    r[t] = n;
    for(int i = 1; i <= t; i++)
        for(int j = l[i]; j <= r[i]; j++){
            pos[j] = i;
            sort(b + l[i], b + r[i] + 1);
        }
    while(q--){
        char op;
        int x, y, z;
        cin >> op >> x >> y >> z;
        if(op == 'M')
            add(x, y, z);
        else
            printf("%d\n", ask(x, y, z));
    }
    return 0;
}

by _x_y_2024 @ 2023-08-17 12:48:58

评测记录:https://www.luogu.com.cn/record/121366499


by BVVD_FM @ 2023-11-11 08:06:48

过了吗?


|