#include <cstdio> #include <cstring> #include <climits> #include <algorithm> #define double long double typedef long long ll; const int MAX_N = 100000; double x[MAX_N + 1], y[MAX_N + 1]; double sum[MAX_N + 1], sum2[MAX_N + 1]; inline void prepare() { sum[0] = 0, sum2[0] = 0; for (int i = 1; i <= MAX_N; i++) { sum[i] = sum[i - 1] + i; sum2[i] = sum2[i - 1] + (double)i * i; } } inline double calc(int l, int r) { return sum[r] - sum[l - 1]; } inline double calc2(int l, int r) { return sum2[r] - sum2[l - 1]; } struct Segt { int l, r; Segt *lc, *rc; double sx, sy, sxy, sxx; double tags, tagt; double cs, ct; bool changed; Segt(int l, int r, Segt *lc, Segt *rc) : l(l), r(r), lc(lc), rc(rc), sx(lc->sx + rc->sx), sy(lc->sy + rc->sy), sxy(lc->sxy + rc->sxy), sxx(lc->sxx + rc->sxx), tags(0), tagt(0), cs(0), ct(0), changed(false) {} Segt(int l, int r, Segt *lc, Segt *rc, double sx, double sy) : l(l), r(r), lc(lc), rc(rc), sx(sx), sy(sy), sxy(sx * sy), sxx(sx * sx), tags(0), tagt(0), cs(0), ct(0), changed(false) {} double querysx(int l, int r) { if (l > this->r || r < this->l) return 0; else if (l <= this->l && r >= this->r) return sx; else return pushDown(), lc->querysx(l, r) + rc->querysx(l, r); } double querysy(int l, int r) { if (l > this->r || r < this->l) return 0; else if (l <= this->l && r >= this->r) return sy; else return pushDown(), lc->querysy(l, r) + rc->querysy(l, r); } double querysxy(int l, int r) { if (l > this->r || r < this->l) return 0; else if (l <= this->l && r >= this->r) return sxy; else return pushDown(), lc->querysxy(l, r) + rc->querysxy(l, r); } double querysxx(int l, int r) { if (l > this->r || r < this->l) return 0; else if (l <= this->l && r >= this->r) return sxx; else return pushDown(), lc->querysxx(l, r) + rc->querysxx(l, r); } void validate() { double sx, sy, sxy, sxx; sx = this->sx; sy = this->sy; sxy = this->sxy; sxx = this->sxx; printf("Segt, sx : %lld, sy : %lld, sxy : %lld, sxx : %lld\n", (long long)sx, (long long)sy, (long long)sxy, (long long)sxx); sx = 0, sy = 0, sxy = 0, sxx = 0; for (int i = l; i <= r; i++) { sx += x[i]; sy += y[i]; sxy += (long long)x[i] * y[i]; sxx += (long long)x[i] * x[i]; } printf("Force, sx : %lld, sy : %lld, sxy : %lld, sxx : %lld\n", (long long)sx, (long long)sy, (long long)sxy, (long long)sxx); } void add(double s, double t) { sxy = sxy + sx * t + sy * s + s * t * (this->r - this->l + 1); sxx = sxx + s * s * (this->r - this->l + 1) + 2 * sx * s; sx += s * (this->r - this->l + 1); sy += t * (this->r - this->l + 1); tags += s; tagt += t; } void change(double s, double t) { double sump = calc(l, r), sumq = calc2(l, r); tags = 0, tagt = 0; int len = r - l + 1; sx = len * s + sump; sy = len * t + sump; sxy = len * s * t + sump * (s + t) + sumq; sxx = s * s * len + sumq + 2 * s * sump; cs = s, ct = t; changed = true; } void maintain() { sx = lc->sx + rc->sx; sy = lc->sy + rc->sy; sxy = lc->sxy + rc->sxy; sxx = lc->sxx + rc->sxx; } void pushDown() { if (changed) { lc->change(cs, ct); rc->change(cs, ct); changed = false; } if (tags != 0 || tagt != 0) { lc->add(tags, tagt); rc->add(tags, tagt); tags = 0, tagt = 0; } } void modify2(int l, int r, int s, int t) { if (l > this->r || r < this->l) return; else if (l <= this->l && r >= this->r) add(s, t); else pushDown(), lc->modify2(l, r, s, t), rc->modify2(l, r, s, t), maintain(); } void change(int l, int r, int s, int t) { if (l > this->r || r < this->l) return; else if (l <= this->l && r >= this->r) change(s, t); else pushDown(), lc->change(l, r, s, t), rc->change(l, r, s, t), maintain(); } static Segt *build(int l, int r) { if (l == r) { return new Segt(l, r, NULL, NULL, x[l], y[l]); } else { int mid = l + (r - l) / 2; return new Segt(l, r, build(l, mid), build(mid + 1, r)); } } } *segt; inline void query(int l, int r) { double sxy = segt->querysxy(l, r); double sx = segt->querysx(l, r); double sy = segt->querysy(l, r); double sxx = segt->querysxx(l, r); double xa = (double)sx / (double)(r - l + 1); double ya = (double)sy / (double)(r - l + 1); double up = sxy - (double)sx * ya - (double)sy * xa + xa * ya * (double)(r - l + 1); double down = sxx + xa * xa * (double)(r - l + 1) - 2 * sx * xa; double ans = up / down; printf("%.10Lf\n", ans); } inline void modify2(int l, int r, double s, double t) { for (int i = l; i <= r; i++) { x[i] += s, y[i] += t; } } inline void change(int l, int r, double s, double t) { for (int i = l; i <= r; i++) { x[i] = s + i, y[i] = t + i; } } int main() { freopen("relative.in", "r", stdin); freopen("relative.out", "w", stdout); int n, m; prepare(); scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) scanf("%Lf", &x[i]); for (int i = 1; i <= n; i++) scanf("%Lf", &y[i]); segt = Segt::build(1, n); for (int i = 1; i <= m; i++) { int cmd; scanf("%d", &cmd); if (cmd == 1) { int l, r; scanf("%d %d", &l, &r); query(l, r); } else if (cmd == 2) { int l, r, s, t; scanf("%d %d %d %d", &l, &r, &s, &t); segt->modify2(l, r, s, t); } else if (cmd == 3) { int l, r, s, t; scanf("%d %d %d %d", &l, &r, &s, &t); segt->change(l, r, s, t); } } fclose(stdin), fclose(stdout); return 0; }
|