https://www.luogu.org/problemnew/show/P1471
线段树维护区间数的平方之和与和
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10; #define DB double #define gc getchar() #define lson jd << 1 #define rson jd << 1 | 1 int n, m; DB Answer, x_, imp_, W[N << 2], F[N << 2], A_2[N << 2], size[N << 2]; struct Read { inline int read_int() { int x = 0; char c = gc; while(c < ‘0‘ || c > ‘9‘) c = gc; while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = gc; return x; } inline DB read_DB() {DB x; scanf("%lf", &x); return x;} }ac; void Build_tree(int l, int r, int jd) { size[jd] = (r - l + 1); if(l == r) { W[jd] = ac.read_DB(); A_2[jd] = W[jd] * W[jd]; return ; } int mid = (l + r) >> 1; Build_tree(l, mid, lson); Build_tree(mid + 1, r, rson); W[jd] = W[lson] + W[rson]; A_2[jd] = A_2[lson] + A_2[rson]; } void Down(int jd) { DB yj = F[jd]; F[lson] += yj; F[rson] += yj; A_2[lson] += (2 * yj * W[lson] + size[lson] * yj * yj); A_2[rson] += (2 * yj * W[rson] + size[rson] * yj * yj); W[lson] += size[lson] * yj; W[rson] += size[rson] * yj; F[jd] = 0; } void Sec_G(int l, int r, int jd, int x, int y, DB yj) { if(x <= l && r <= y) { F[jd] += yj; A_2[jd] += (2 * yj * W[jd] + size[jd] * yj * yj); W[jd] += size[jd] * yj; return ; } if(F[jd]) Down(jd); int mid = (l + r) >> 1; if(x <= mid) Sec_G(l, mid, lson, x, y, yj); if(y > mid) Sec_G(mid + 1, r, rson, x, y, yj); W[jd] = W[lson] + W[rson]; A_2[jd] = A_2[lson] + A_2[rson]; } void Sec_A_w(int l, int r, int jd, int x, int y) { if(x <= l && r <= y) { Answer += W[jd]; return ; } if(F[jd]) Down(jd); int mid = (l + r) >> 1; if(x <= mid) Sec_A_w(l, mid, lson, x, y); if(y > mid) Sec_A_w(mid + 1, r, rson, x, y); } void Sec_A_A(int l, int r, int jd, int x, int y) { if(x <= l && r <= y) { imp_ += A_2[jd]; return ; } if(F[jd]) Down(jd); int mid = (l + r) >> 1; if(x <= mid) Sec_A_A(l, mid, lson, x, y); if(y > mid) Sec_A_A(mid + 1, r, rson, x, y); } int main() { n = ac.read_int(); m = ac.read_int(); Build_tree(1, n, 1); while(m --) { int opt = ac.read_int(); if(opt == 1) { int x = ac.read_int(), y = ac.read_int(), k = ac.read_DB(); Sec_G(1, n, 1, x, y, k); } else if(opt == 2) { Answer = 0; int x = ac.read_int(), y = ac.read_int(); Sec_A_w(1, n, 1, x, y); printf("%.4lf\n", Answer / (y - x + 1)); } else { Answer = 0; int x = ac.read_int(), y = ac.read_int(); Sec_A_w(1, n, 1, x, y); x_ = Answer / (y - x + 1); imp_ = 0; Sec_A_A(1, n, 1, x, y); DB answer = imp_ - 2 * x_ * Answer + (y - x + 1) * x_ * x_; printf("%.4lf\n", answer / (y - x + 1)); } } return 0; }