0pts求调(估计是精度问题)
查看原帖
0pts求调(估计是精度问题)
905636
_xguagua_Firefly_楼主2024/7/18 16:09

精度问题怎么解决啊

#include <bits/stdc++.h>
#define int long long
#define eps 1e-9
#define ld double
using namespace std;

const int MAXN = 1e5 + 114;
int n,m,op,x,y,k;
long double o[MAXN];
struct node
{
    int l,r;
    ld lazy,sum,sqm;
    int len() {return r - l + 1;}
}tree[MAXN << 2];
void pushup(int rt)
{
    tree[rt].sum = tree[rt << 1].sum + tree[(rt << 1) + 1].sum;
    tree[rt].sqm = tree[rt << 1].sqm + tree[(rt << 1) + 1].sqm;
}
void pushdown(int rt)
{
    if(tree[rt].lazy)
    {
        ld dt = tree[rt].lazy;
        tree[rt << 1].sqm += 2 * dt * tree[rt << 1].sum + tree[rt << 1].len() * dt * dt;
        tree[(rt << 1) + 1].sqm += 2 * dt * tree[(rt << 1) + 1].sum + tree[rt << 1].len() * dt * dt;
        tree[rt << 1].sum += tree[rt << 1].len() * dt;
        tree[(rt << 1) + 1].sum += tree[(rt << 1) + 1].len() * dt;
        tree[rt].lazy = 0.0;
    }
}
void build(int l,int r,int rt)
{
    tree[rt].l = l,tree[rt].r = r;
    if(l == r) 
    {
        tree[rt].sum = (ld)o[l];
        tree[rt].sqm = (ld)o[l] * (ld)o[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(l,mid,rt << 1);
    build(mid + 1,r,(rt << 1) + 1);
    pushup(rt);
}
void add(int l,int r,int rt,ld k)
{
    int s = tree[rt].l,t = tree[rt].r;
    if(l <= s && r >= t)
    {
        tree[rt].sqm += 2 * tree[rt].sum * k + tree[rt].len() * k * k;
        tree[rt].sum += k * tree[rt].len();
        tree[rt].lazy += k;
        return;
    }
    pushdown(rt);
    int mid = (s + t) >> 1;
    if(l <= mid) add(l,r,rt << 1,k);
    if(r > mid) add(l,r,(rt << 1) + 1,k);
    pushup(rt);
}
ld query1(int l,int r,int rt)
{
    int s = tree[rt].l,t = tree[rt].r;
    if(l <= s && r >= t) return tree[rt].sum;
    pushdown(rt);
    ld res = 0.0;
    int mid = (s + t) >> 1;
    if(l <= mid) res += query1(l,r,rt << 1);
    if(r > mid) res += query1(l,r,(rt << 1) + 1);
    return res;
}
ld query2(int l,int r,int rt)
{
    int s = tree[rt].l,t = tree[rt].r;
    if(l <= s && r >= t) return tree[rt].sqm;
    pushdown(rt);
    ld res = 0.0;
    int mid = (s + t) >> 1;
    if(l <= mid) res += query2(l,r,rt << 1);
    if(r > mid) res += query2(l,r,(rt << 1) + 1);
    return res;
}
signed main()
{
    cin >> n >> m;
    for(int i = 1;i <= n;i++) cin >> o[i];
    build(1,n,1);
    while(m--)
    {
        cin >> op;
        if(op == 1)
        {
            cin >> x >> y >> k;
            add(x,y,1,k);
        }
        else if (op == 2)
        {
            cin >> x >> y;
            printf("%.4lf\n",(query1(x,y,1) / (y - x + 1)));
        }
        else
        {
            cin >> x >> y;
            printf("%.4lf\n",((query2(x,y,1) / (y - x + 1)) - (query1(x,y,1) / (y - x + 1)) * (query1(x,y,1) / (y - x + 1))));
        } 
    }
    return 0;
}
2024/7/18 16:09
加载中...