#1、2、3、4、9、10测试点WA
找不到问题出在哪里
蒟蒻跪求路过大佬帮忙,看一下思路和代码.
设一个位置原本的值为a,增加的值为Δa
len表示区间长度,sum表示区间和
区间平方和 Σa2 变成 Σ(a+Δa)2
区间平方和增加值为Σ[(a+Δa)2−Σa2]
展开得到:Σ(2aΔa+Δa2)
=2∗sum∗Δa+len∗Δa2
#include <bits/stdc++.h>
using namespace std;
#define ll double //不好的习惯,被实数要求暴击
int n, m, cmd, x, y;
ll k;
ll t[100010], tree[100010 * 4], treepow2[100010 * 4];//数组,区间和,区间平方和
ll lzy[100010 * 4];//破lazy_tag
void push_up(int pos) {
tree[pos] = tree[pos*2] + tree[pos*2 + 1];
treepow2[pos] = treepow2[pos*2] + treepow2[pos*2 + 1];
return;
}
void pushdown_lazytag(int l, int r, int u) {
int M = (l + r) / 2;
lzy[2 * u] += lzy[u];
treepow2[2*u]+=2*tree[2*u]*lzy[u]+(M - l+1)*lzy[u]*lzy[u];
tree[2 * u] += (M - l+1) * lzy[u];
lzy[2 * u + 1] += lzy[u];
treepow2[2*u+1]+=2*tree[2*u+1]*lzy[u]+(r - M)*lzy[u]*lzy[u];
tree[2 * u + 1] += (r - M) * lzy[u];
lzy[u] = 0.0;
return;
}
void build(int u, int l, int r) {
if (l == r) {
tree[u] = t[l];
treepow2[u] = t[l]*t[l];
return;
}
int m = (l + r) / 2;
build(2 * u, l, m);
build(2 * u + 1, m + 1, r);
push_up(u);
}
void update(int u, int l, int r, int x, int y, double k) { //l,r:当前范围 x,y:目标范围 k:更改值 区间修改
if (l >= x && y >= r) { //被包含
treepow2[u]+=2.0*tree[u]*k+(r-l+1)*k*k;
tree[u]+=k*(r-l+1);//************************************************
lzy[u] += k;
} else if ((x > r) || (y < l)) { //完全没有交集
return;
} else { //不完全包含,马上向下追查
int m = (l + r) / 2;
pushdown_lazytag(l, r,u);//*******************************************
update(u * 2, l, m, x, y, k);
update(u * 2 + 1, m + 1, r, x, y, k);
push_up(u);
}
//DEBUG
//cout<<"DEBUG"<<treepow2[u]<<" "<<l<<" "<<r<<endl;
return;
}
ll query(int u, int l, int r, int x, int y) { //l,r:查询范围 x,y:目标范围 区间查询
if (l >= x && y >= r) { //被包含
return tree[u];
} else if ((x > r) || (y < l)) { //完全没有交集
return 0;
} else { //不完全对应,向下追查
int m = (l + r) / 2;
pushdown_lazytag(l, r, u);
return query(u * 2, l, m, x, y) + query(u * 2 + 1, m + 1, r, x, y);
}
}
ll quepow2(int u, int l, int r, int x, int y) { //l,r:查询范围 x,y:目标范围 区间查询
if (l >= x && y >= r) { //被包含
return treepow2[u];
} else if ((x > r) || (y < l)) { //完全没有交集
return 0;
} else { //不完全对应,向下追查
int m = (l + r) / 2;
pushdown_lazytag(l, r, u);
return quepow2(u * 2, l, m, x, y) + quepow2(u * 2 + 1, m + 1, r, x, y);
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> t[i];
}
build(1, 1, n);
while (m--) {
cin >> cmd;
double k;
if (cmd == 1) {
cin >> x >> y >> k;
update(1, 1, n, x, y, k);
}
else if (cmd==2){
cin>>x>>y;
double adv=1.0*query(1,1,n,x,y)/(y-x+1);
printf("%.4f\n",adv);
}
else{
cin>>x>>y;
double adv=1.0*query(1,1,n,x,y)/(y-x+1);
printf("%.4f\n",1.0*quepow2(1,1,n,x,y)/n-2.0*adv/n*query(1,1,n,x,y)+1.0*adv*adv);
}
}
return 0;
}
谢谢!!