40pts求调,已经排除部分常见错误(见内)
  • 板块P1471 方差
  • 楼主Mushroom_1965
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/10/20 09:01
  • 上次更新2024/10/20 11:13:02
查看原帖
40pts求调,已经排除部分常见错误(见内)
883309
Mushroom_1965楼主2024/10/20 09:01

1、和与平方和在下传和更新时的先后次序是先平方和再和;
2、输入的原数组、所有被维护的数组以及更新时的 kk 开double;
3、所有应下放的地方全已经下放;
目测区间和没有问题,问题大概率出在平方和上,AC on #5#6#7#8。

#include <iomanip>
#include <iostream>
using namespace std;

const int N = 1e5;
int n, m;
double a[N + 3];
namespace segment_tree {
    double data1[(N << 2) + 3], data2[(N << 2) + 3], lz[(N << 2) + 3] = {0};
    void build(int p, int l, int r) {
        if (l == r) {
            data1[p] = a[l], data2[p] = a[l] * a[l];
            return;
        }
        int mid = l + r >> 1;
        build(p << 1, l, mid);
        build(p << 1 | 1, mid + 1, r);
        data1[p] = data1[p << 1] + data1[p << 1 | 1];
        data2[p] = data2[p << 1] + data2[p << 1 | 1];
        return;
    }
    void pushdown(int p, int l, int r) {
        int mid = l + r >> 1;
        data2[p << 1] += 2.00 * lz[p] * data2[p << 1] + (mid - l + 1) * lz[p] * lz[p];
        data2[p << 1 | 1] += 2.00 * lz[p] * data2[p << 1 | 1] + (r - mid) * lz[p] * lz[p];
        data1[p << 1] += lz[p] * (mid - l + 1);
        data1[p << 1 | 1] += lz[p] * (r - mid);
        lz[p << 1] += lz[p];
        lz[p << 1 | 1] += lz[p];
        lz[p] = 0;
        return;
    }
    void update(int p, int l, int r, int x, int y, double k) {
        if (l >= x && r <= y) {
            data2[p] += 2.00 * k * data1[p] + (r - l + 1) * k * k;
            data1[p] += k * (r - l + 1);
            lz[p] += k;
            return;
        }
        if (lz[p]) pushdown(p, l, r);
        int mid = l + r >> 1;
        if (x <= mid) update(p << 1, l, mid, x, y, k);
        if (y > mid) update(p << 1 | 1, mid + 1, r, x, y, k);
        data1[p] = data1[p << 1] + data1[p << 1 | 1];
        data2[p] = data2[p << 1] + data2[p << 1 | 1];
        return;
    }
    double query1(int p, int l, int r, int x, int y) {
        if (l >= x && r <= y) return data1[p];
        if (lz[p]) pushdown(p, l, r);
        double res = 0.00;
        int mid = l + r >> 1;
        if (x <= mid) res += query1(p << 1, l, mid, x, y);
        if (y > mid) res += query1(p << 1 | 1, mid + 1, r, x, y);
        return res;
    }
    double query2(int p, int l, int r, int x, int y) {
        if (l >= x && r <= y) return data2[p];
        if (lz[p]) pushdown(p, l, r);
        double res = 0.00;
        int mid = l + r >> 1;
        if (x <= mid) res += query2(p << 1, l, mid, x, y);
        if (y > mid) res += query2(p << 1 | 1, mid + 1, r, x, y);
        return res;
    }
}
int main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i++) cin >> a[i];
    segment_tree::build(1, 1, n);
    while (m--) {
        double k;
        int op, x, y;
        cin >> op;
        switch (op) {
            case 1:
                cin >> x >> y >> k;
                segment_tree::update(1, 1, n, x, y, k);
                break;
            case 2:
                cin >> x >> y;
                cout << fixed << setprecision(4) << segment_tree::query1(1, 1, n, x, y) / (y - x + 1) << '\n';
                break;
            case 3:
                cin >> x >> y;
                cout << fixed << setprecision(4) << segment_tree::query2(1, 1, n, x, y) / (y - x + 1)
                                                    - segment_tree::query1(1, 1, n, x, y) / (y - x + 1)
                                                    * segment_tree::query1(1, 1, n, x, y) / (y - x + 1) << '\n';
                break;
        }
    }
    return 0;
}
2024/10/20 09:01
加载中...