RT,线段树感觉本身没有什么问题,也50分了,但是有五个点好像数据很大精度就比较要命就被卡了,求助!
#include <iostream>
#include <iomanip>
#include <cstdio>
#define MAXN 1000005
using namespace std;
struct node {
int l, r;
double xy, x, y, x2, tag_x, tag_y;
} tree[8 * MAXN];
int n, m;
double x[MAXN], y[MAXN];
inline void pushdown(int i) {
if (tree[i].tag_x || tree[i].tag_y) {
tree[i * 2].x2 += 2 * tree[i].tag_x * tree[i * 2].x +
(tree[i * 2].r - tree[i * 2].l + 1) * tree[i].tag_x * tree[i].tag_x;
tree[i * 2].xy += tree[i].tag_x * tree[i * 2].y + tree[i].tag_y * tree[i * 2].x +
(tree[i * 2].r - tree[i * 2].l + 1) * tree[i].tag_x * tree[i].tag_y;
tree[i * 2].x += (tree[i * 2].r - tree[i * 2].l + 1) * tree[i].tag_x;
tree[i * 2].y += (tree[i * 2].r - tree[i * 2].l + 1) * tree[i].tag_y;
tree[i * 2 + 1].x2 += 2 * tree[i].tag_x * tree[i * 2 + 1].x +
(tree[i * 2 + 1].r - tree[i * 2 + 1].l + 1) * tree[i].tag_x * tree[i].tag_x;
tree[i * 2 + 1].xy += tree[i].tag_x * tree[i * 2 + 1].y + tree[i].tag_y * tree[i * 2 + 1].x +
(tree[i * 2 + 1].r - tree[i * 2 + 1].l + 1) * tree[i].tag_x * tree[i].tag_y;
tree[i * 2 + 1].x += (tree[i * 2 + 1].r - tree[i * 2 + 1].l + 1) * tree[i].tag_x;
tree[i * 2 + 1].y += (tree[i * 2 + 1].r - tree[i * 2 + 1].l + 1) * tree[i].tag_y;
tree[i * 2].tag_x += tree[i].tag_x, tree[i * 2].tag_y += tree[i].tag_y;
tree[i * 2 + 1].tag_x += tree[i].tag_x, tree[i * 2 + 1].tag_y += tree[i].tag_y;
tree[i].tag_x = 0, tree[i].tag_y = 0;
}
return;
}
inline void pushup(int i) {
tree[i].x = tree[i * 2].x + tree[i * 2 + 1].x;
tree[i].xy = tree[i * 2].xy + tree[i * 2 + 1].xy;
tree[i].x2 = tree[i * 2].x2 + tree[i * 2 + 1].x2;
tree[i].y = tree[i * 2].y + tree[i * 2 + 1].y;
return;
}
inline void build(int i, int l, int r) {
tree[i].l = l, tree[i].r = r, tree[i].tag_x = 0, tree[i].tag_y = 0;
if (l == r) {
tree[i].xy = x[l] * y[l], tree[i].x = x[l], tree[i].y = y[l], tree[i].x2 = x[l] * x[l];
return;
}
int mid = (l + r) >> 1;
build(i * 2, l, mid), build(i * 2 + 1, mid + 1, r);
pushup(i);
return;
}
inline double ask(int i, int l, int r,int id) {
if (tree[i].l >= l && tree[i].r <= r) {
if(id==1)
return tree[i].x;
if(id==2)
return tree[i].y;
if(id==3)
return tree[i].x2;
return tree[i].xy;
}
int mid = (tree[i].l + tree[i].r) >> 1;
pushdown(i);
double res = 0;
if (mid >= l)
res += ask(i * 2, l, r,id);
if (mid + 1 <= r)
res += ask(i * 2 + 1, l, r,id);
return res;
}
inline void update(int i, int l, int r, double x, double y) {
if (tree[i].l >= l && tree[i].r <= r) {
tree[i].x2 += 2 * x * tree[i].x + (tree[i].r - tree[i].l + 1) * x * x;
tree[i].xy += x * tree[i].y + y * tree[i].x + (tree[i].r - tree[i].l + 1) * x * y;
tree[i].x += (tree[i].r - tree[i].l + 1) * x;
tree[i].y += (tree[i].r - tree[i].l + 1) * y;
tree[i].tag_x += x, tree[i].tag_y += y;
return;
}
int mid = (tree[i].l + tree[i].r) >> 1;
pushdown(i);
if (mid >= l)
update(i * 2, l, r, x, y);
if (mid + 1 <= r)
update(i * 2 + 1, l, r, x, y);
pushup(i);
return;
}
inline void clean(int i, int l, int r) {
if (tree[i].l >= l && tree[i].r <= r) {
tree[i].xy = tree[i].x2 = tree[i].r * (tree[i].r + 1) * (2 * tree[i].r + 1) / 6.0 -
tree[i].l * (tree[i].l - 1) * (2 * tree[i].l - 1) / 6.0;
tree[i].x = tree[i].y = (tree[i].r - tree[i].l + 1) * (tree[i].l + tree[i].r) / 2.0;
tree[i].tag_x = tree[i].tag_y = 0;
return;
}
pushdown(i);
int mid = (tree[i].l + tree[i].r) >> 1;
if (mid >= l)
clean(i * 2, l, r);
if (mid + 1 <= r)
clean(i * 2 + 1, l, r);
pushup(i);
return;
}
int main() {
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]);
build(1, 1, n);
while (m--) {
int op, l, r;
scanf("%d%d%d", &op, &l, &r);
if (op == 1){
double length = double(r - l + 1);
double px = ask(1, l,r, 1) / length;
double py = ask(1,l,r, 2) / length;
double frac_1 = ask(1,l,r, 4) - px * py * length;
double frac_2 = ask(1,l,r, 3) - px * px * length;
printf("%.10lf\n",frac_1/frac_2);
}
else {
double s, t;
scanf("%lf%lf", &s, &t);
if (op == 2)
update(1, l, r, s, t);
else if (op == 3) {
clean(1, l, r);
update(1, l, r, s, t);
}
}
}
return 0;
}